Skip to content

Commit a1a240b

Browse files
Aditya Nandakumarhyp
authored andcommitted
[GISel]: Add Opcodes for CTLZ/CTTZ/CTPOP
https://reviews.llvm.org/D48600 Added IRTranslator support to translate these known intrinsics into GISel opcodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338944 91177308-0d34-0410-b5e6-96231b3b80d8 (cherry picked from commit a347456)
1 parent 1a245aa commit a1a240b

File tree

8 files changed

+127
-17
lines changed

8 files changed

+127
-17
lines changed

include/llvm/Support/TargetOpcodes.def

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,21 @@ HANDLE_TARGET_OPCODE(G_EXTRACT_VECTOR_ELT)
464464
/// Generic shufflevector.
465465
HANDLE_TARGET_OPCODE(G_SHUFFLE_VECTOR)
466466

467+
/// Generic count trailing zeroes.
468+
HANDLE_TARGET_OPCODE(G_CTTZ)
469+
470+
/// Same as above, undefined for zero inputs.
471+
HANDLE_TARGET_OPCODE(G_CTTZ_ZERO_UNDEF)
472+
473+
/// Generic count leading zeroes.
474+
HANDLE_TARGET_OPCODE(G_CTLZ)
475+
476+
/// Same as above, undefined for zero inputs.
477+
HANDLE_TARGET_OPCODE(G_CTLZ_ZERO_UNDEF)
478+
479+
/// Generic count bits.
480+
HANDLE_TARGET_OPCODE(G_CTPOP)
481+
467482
/// Generic byte swap.
468483
HANDLE_TARGET_OPCODE(G_BSWAP)
469484

include/llvm/Target/GenericOpcodes.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,36 @@ def G_VAARG : GenericInstruction {
120120
let mayStore = 1;
121121
}
122122

123+
def G_CTLZ : GenericInstruction {
124+
let OutOperandList = (outs type0:$dst);
125+
let InOperandList = (ins type0:$src);
126+
let hasSideEffects = 0;
127+
}
128+
129+
def G_CTLZ_ZERO_UNDEF : GenericInstruction {
130+
let OutOperandList = (outs type0:$dst);
131+
let InOperandList = (ins type0:$src);
132+
let hasSideEffects = 0;
133+
}
134+
135+
def G_CTTZ : GenericInstruction {
136+
let OutOperandList = (outs type0:$dst);
137+
let InOperandList = (ins type0:$src);
138+
let hasSideEffects = 0;
139+
}
140+
141+
def G_CTTZ_ZERO_UNDEF : GenericInstruction {
142+
let OutOperandList = (outs type0:$dst);
143+
let InOperandList = (ins type0:$src);
144+
let hasSideEffects = 0;
145+
}
146+
147+
def G_CTPOP : GenericInstruction {
148+
let OutOperandList = (outs type0:$dst);
149+
let InOperandList = (ins type0:$src);
150+
let hasSideEffects = 0;
151+
}
152+
123153
def G_BSWAP : GenericInstruction {
124154
let OutOperandList = (outs type0:$dst);
125155
let InOperandList = (ins type0:$src);

lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,26 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
913913
PtrTy.getSizeInBits() / 8, 8));
914914
return true;
915915
}
916+
case Intrinsic::cttz:
917+
case Intrinsic::ctlz: {
918+
ConstantInt *Cst = cast<ConstantInt>(CI.getArgOperand(1));
919+
bool isTrailing = ID == Intrinsic::cttz;
920+
unsigned Opcode = isTrailing
921+
? Cst->isZero() ? TargetOpcode::G_CTTZ
922+
: TargetOpcode::G_CTTZ_ZERO_UNDEF
923+
: Cst->isZero() ? TargetOpcode::G_CTLZ
924+
: TargetOpcode::G_CTLZ_ZERO_UNDEF;
925+
MIRBuilder.buildInstr(Opcode)
926+
.addDef(getOrCreateVReg(CI))
927+
.addUse(getOrCreateVReg(*CI.getArgOperand(0)));
928+
return true;
929+
}
930+
case Intrinsic::ctpop: {
931+
MIRBuilder.buildInstr(TargetOpcode::G_CTPOP)
932+
.addDef(getOrCreateVReg(CI))
933+
.addUse(getOrCreateVReg(*CI.getArgOperand(0)));
934+
return true;
935+
}
916936
}
917937
return false;
918938
}

test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,36 @@ define float @test_fabs_intrin(float %a) {
14081408
ret float %res
14091409
}
14101410

1411+
declare i32 @llvm.ctlz.i32(i32, i1)
1412+
define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1413+
; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1414+
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1415+
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1416+
; CHECK: $w0 = COPY [[RES]]
1417+
%res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1418+
ret i32 %res
1419+
}
1420+
1421+
declare i32 @llvm.cttz.i32(i32, i1)
1422+
define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1423+
; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1424+
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1425+
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1426+
; CHECK: $w0 = COPY [[RES]]
1427+
%res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1428+
ret i32 %res
1429+
}
1430+
1431+
declare i32 @llvm.ctpop.i32(i32)
1432+
define i32 @test_ctpop_intrinsic(i32 %a) {
1433+
; CHECK-LABEL: name: test_ctpop
1434+
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1435+
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1436+
; CHECK: $w0 = COPY [[RES]]
1437+
%res = call i32 @llvm.ctpop.i32(i32 %a)
1438+
ret i32 %res
1439+
}
1440+
14111441
declare void @llvm.lifetime.start.p0i8(i64, i8*)
14121442
declare void @llvm.lifetime.end.p0i8(i64, i8*)
14131443
define void @test_lifetime_intrin() {

test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,21 @@
282282
# DEBUG-NEXT: G_SHUFFLE_VECTOR (opcode {{[0-9]+}}): 3 type indices
283283
# DEBUG: .. type index coverage check SKIPPED: no rules defined
284284
#
285+
# DEBUG-NEXT: G_CTTZ (opcode {{[0-9]+}}): 1 type index
286+
# DEBUG: .. type index coverage check SKIPPED: no rules defined
287+
#
288+
# DEBUG-NEXT: G_CTTZ_ZERO_UNDEF (opcode {{[0-9]+}}): 1 type index
289+
# DEBUG: .. type index coverage check SKIPPED: no rules defined
290+
#
291+
# DEBUG-NEXT: G_CTLZ (opcode {{[0-9]+}}): 1 type index
292+
# DEBUG: .. type index coverage check SKIPPED: no rules defined
293+
#
294+
# DEBUG-NEXT: G_CTLZ_ZERO_UNDEF (opcode {{[0-9]+}}): 1 type index
295+
# DEBUG: .. type index coverage check SKIPPED: no rules defined
296+
#
297+
# DEBUG-NEXT: G_CTPOP (opcode {{[0-9]+}}): 1 type index
298+
# DEBUG: .. type index coverage check SKIPPED: no rules defined
299+
#
285300
# DEBUG-NEXT: G_BSWAP (opcode {{[0-9]+}}): 1 type index
286301
# DEBUG: .. the first uncovered type index: 1, OK
287302

test/TableGen/trydecode-emission.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ def InstB : TestInstruction {
3434
}
3535

3636
// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
37-
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 16, 0, 0, // Skip to: 24
38-
// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, 0, // Skip to: 21
39-
// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 21
40-
// CHECK-NEXT: /* 21 */ MCD::OPC_Decode, {{[0-9]+}}, 1, // Opcode: InstA
41-
// CHECK-NEXT: /* 24 */ MCD::OPC_Fail,
37+
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 18, 0, 0, // Skip to: 26
38+
// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 22
39+
// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, 1, 0, 0, 0, 0, // Opcode: InstB, skip to: 22
40+
// CHECK-NEXT: /* 22 */ MCD::OPC_Decode, {{[0-9]+}}, 1, 1, // Opcode: InstA
41+
// CHECK-NEXT: /* 26 */ MCD::OPC_Fail,
4242

4343
// CHECK: if (DecodeInstB(MI, insn, Address, Decoder) == MCDisassembler::Fail) { DecodeComplete = false; return MCDisassembler::Fail; }

test/TableGen/trydecode-emission2.td

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ def InstB : TestInstruction {
3131
}
3232

3333
// CHECK: /* 0 */ MCD::OPC_ExtractField, 2, 1, // Inst{2} ...
34-
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 34, 0, 0, // Skip to: 42
34+
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 36, 0, 0, // Skip to: 44
3535
// CHECK-NEXT: /* 8 */ MCD::OPC_ExtractField, 5, 3, // Inst{7-5} ...
36-
// CHECK-NEXT: /* 11 */ MCD::OPC_FilterValue, 0, 26, 0, 0, // Skip to: 42
37-
// CHECK-NEXT: /* 16 */ MCD::OPC_CheckField, 0, 2, 3, 6, 0, 0, // Skip to: 29
38-
// CHECK-NEXT: /* 23 */ MCD::OPC_TryDecode, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 29
39-
// CHECK-NEXT: /* 29 */ MCD::OPC_CheckField, 3, 2, 0, 6, 0, 0, // Skip to: 42
40-
// CHECK-NEXT: /* 36 */ MCD::OPC_TryDecode, {{[0-9]+}}, 1, 0, 0, 0, // Opcode: InstA, skip to: 42
41-
// CHECK-NEXT: /* 42 */ MCD::OPC_Fail,
36+
// CHECK-NEXT: /* 11 */ MCD::OPC_FilterValue, 0, 28, 0, 0, // Skip to: 44
37+
// CHECK-NEXT: /* 16 */ MCD::OPC_CheckField, 0, 2, 3, 7, 0, 0, // Skip to: 30
38+
// CHECK-NEXT: /* 23 */ MCD::OPC_TryDecode, {{[0-9]+}}, 1, 0, 0, 0, 0, // Opcode: InstB, skip to: 30
39+
// CHECK-NEXT: /* 30 */ MCD::OPC_CheckField, 3, 2, 0, 7, 0, 0, // Skip to: 44
40+
// CHECK-NEXT: /* 37 */ MCD::OPC_TryDecode, {{[0-9]+}}, 1, 1, 0, 0, 0, // Opcode: InstA, skip to: 44
41+
// CHECK-NEXT: /* 44 */ MCD::OPC_Fail,
4242

4343
// CHECK: if (DecodeInstB(MI, insn, Address, Decoder) == MCDisassembler::Fail) { DecodeComplete = false; return MCDisassembler::Fail; }
4444
// CHECK: if (DecodeInstA(MI, insn, Address, Decoder) == MCDisassembler::Fail) { DecodeComplete = false; return MCDisassembler::Fail; }

test/TableGen/trydecode-emission3.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ def InstB : TestInstruction {
3535
}
3636

3737
// CHECK: /* 0 */ MCD::OPC_ExtractField, 4, 4, // Inst{7-4} ...
38-
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 16, 0, 0, // Skip to: 24
39-
// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 6, 0, 0, // Skip to: 21
40-
// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, 0, 0, 0, 0, // Opcode: InstB, skip to: 21
41-
// CHECK-NEXT: /* 21 */ MCD::OPC_Decode, {{[0-9]+}}, 1, // Opcode: InstA
42-
// CHECK-NEXT: /* 24 */ MCD::OPC_Fail,
38+
// CHECK-NEXT: /* 3 */ MCD::OPC_FilterValue, 0, 18, 0, 0, // Skip to: 26
39+
// CHECK-NEXT: /* 8 */ MCD::OPC_CheckField, 2, 2, 0, 7, 0, 0, // Skip to: 22
40+
// CHECK-NEXT: /* 15 */ MCD::OPC_TryDecode, {{[0-9]+}}, 1, 0, 0, 0, 0, // Opcode: InstB, skip to: 22
41+
// CHECK-NEXT: /* 22 */ MCD::OPC_Decode, {{[0-9]+}}, 1, 1, // Opcode: InstA
42+
// CHECK-NEXT: /* 26 */ MCD::OPC_Fail,
4343

4444
// CHECK: if (DecodeInstBOp(MI, tmp, Address, Decoder) == MCDisassembler::Fail) { DecodeComplete = false; return MCDisassembler::Fail; }

0 commit comments

Comments
 (0)