Skip to content

Commit 23da702

Browse files
committed
GlobalISel: Translate llvm.fshl/llvm.fshr
1 parent 20eb719 commit 23da702

File tree

6 files changed

+59
-1
lines changed

6 files changed

+59
-1
lines changed

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ HANDLE_TARGET_OPCODE(G_LSHR)
385385
// Generic arithmetic right-shift
386386
HANDLE_TARGET_OPCODE(G_ASHR)
387387

388+
// Generic funnel left shift
389+
HANDLE_TARGET_OPCODE(G_FSHL)
390+
391+
// Generic funnel right shift
392+
HANDLE_TARGET_OPCODE(G_FSHR)
393+
388394
/// Generic integer-base comparison, also applicable to vectors of integers.
389395
HANDLE_TARGET_OPCODE(G_ICMP)
390396

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,22 @@ def G_ASHR : GenericInstruction {
308308
let hasSideEffects = 0;
309309
}
310310

311+
/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
312+
/// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
313+
def G_FSHL : GenericInstruction {
314+
let OutOperandList = (outs type0:$dst);
315+
let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
316+
let hasSideEffects = 0;
317+
}
318+
319+
/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
320+
/// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
321+
def G_FSHR : GenericInstruction {
322+
let OutOperandList = (outs type0:$dst);
323+
let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
324+
let hasSideEffects = 0;
325+
}
326+
311327
// Generic integer comparison.
312328
def G_ICMP : GenericInstruction {
313329
let OutOperandList = (outs type0:$dst);

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
9393
def : GINodeEquiv<G_BR, br>;
9494
def : GINodeEquiv<G_BSWAP, bswap>;
9595
def : GINodeEquiv<G_BITREVERSE, bitreverse>;
96+
def : GINodeEquiv<G_FSHL, fshl>;
97+
def : GINodeEquiv<G_FSHR, fshr>;
9698
def : GINodeEquiv<G_CTLZ, ctlz>;
9799
def : GINodeEquiv<G_CTTZ, cttz>;
98100
def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,12 @@ unsigned IRTranslator::getSimpleIntrinsicOpcode(Intrinsic::ID ID) {
12201220
break;
12211221
case Intrinsic::bswap:
12221222
return TargetOpcode::G_BSWAP;
1223-
case Intrinsic::bitreverse:
1223+
case Intrinsic::bitreverse:
12241224
return TargetOpcode::G_BITREVERSE;
1225+
case Intrinsic::fshl:
1226+
return TargetOpcode::G_FSHL;
1227+
case Intrinsic::fshr:
1228+
return TargetOpcode::G_FSHR;
12251229
case Intrinsic::ceil:
12261230
return TargetOpcode::G_FCEIL;
12271231
case Intrinsic::cos:

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,30 @@ define i32 @test_bitreverse_intrinsic(i32 %a) {
13961396
ret i32 %res
13971397
}
13981398

1399+
declare i32 @llvm.fshl.i32(i32, i32, i32)
1400+
define i32 @test_fshl_intrinsic(i32 %a, i32 %b, i32 %c) {
1401+
; CHECK-LABEL: name: test_fshl_intrinsic
1402+
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1403+
; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1
1404+
; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2
1405+
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHL [[A]], [[B]], [[C]]
1406+
; CHECK: $w0 = COPY [[RES]]
1407+
%res = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
1408+
ret i32 %res
1409+
}
1410+
1411+
declare i32 @llvm.fshr.i32(i32, i32, i32)
1412+
define i32 @test_fshr_intrinsic(i32 %a, i32 %b, i32 %c) {
1413+
; CHECK-LABEL: name: test_fshr_intrinsic
1414+
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1415+
; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1
1416+
; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2
1417+
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHR [[A]], [[B]], [[C]]
1418+
; CHECK: $w0 = COPY [[RES]]
1419+
%res = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
1420+
ret i32 %res
1421+
}
1422+
13991423
declare void @llvm.lifetime.start.p0i8(i64, i8*)
14001424
declare void @llvm.lifetime.end.p0i8(i64, i8*)
14011425
define void @test_lifetime_intrin() {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@
263263
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
264264
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
265265
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
266+
# DEBUG-NEXT: G_FSHL (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
267+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
268+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
269+
# DEBUG-NEXT: G_FSHR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
270+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
271+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
266272
# DEBUG-NEXT: G_ICMP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
267273
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
268274
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected

0 commit comments

Comments
 (0)