Skip to content

Commit 3906037

Browse files
[LLVM][AArch64] Correctly lower funnel shifts by zero.
Prevent LowerFunnelShift from creating an invalid ISD::FSHR when lowering "ISD::FSHL X, Y, 0". Such inputs are rare because it's a NOP that DAGCombiner will optimise away. However, we shoudl not rely on this and so this PR mirror the same optimisation. NOTE: To simiplify testing, this PR also adds a command line option to disable the DAG combiner (-combiner-disabled).
1 parent 8dd0065 commit 3906037

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7266,12 +7266,18 @@ static SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) {
72667266
MVT VT = Op.getSimpleValueType();
72677267

72687268
if (Op.getOpcode() == ISD::FSHL) {
7269+
if (ShiftNo->isZero())
7270+
return Op.getOperand(0);
7271+
72697272
unsigned int NewShiftNo =
72707273
VT.getFixedSizeInBits() - ShiftNo->getZExtValue();
72717274
return DAG.getNode(
72727275
ISD::FSHR, DL, VT, Op.getOperand(0), Op.getOperand(1),
72737276
DAG.getConstant(NewShiftNo, DL, Shifts.getValueType()));
72747277
} else if (Op.getOpcode() == ISD::FSHR) {
7278+
if (ShiftNo->isZero())
7279+
return Op.getOperand(1);
7280+
72757281
return Op;
72767282
}
72777283
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc %s -o - | FileCheck %s
3+
; RUN: llc -combiner-disabled %s -o - | FileCheck %s
4+
5+
target triple = "aarch64-unknown-linux-gnu"
6+
7+
; Verify lowering code in isolation to ensure we can lower shifts that would
8+
; normally be optimised away.
9+
10+
define i32 @fshl_i32_by_zero(i32 %unused, i32 %a, i32 %b) {
11+
; CHECK-LABEL: fshl_i32_by_zero:
12+
; CHECK: // %bb.0:
13+
; CHECK-NEXT: mov w0, w1
14+
; CHECK-NEXT: ret
15+
%r = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 zeroinitializer)
16+
ret i32 %r
17+
}
18+
19+
define i64 @fshl_i64_by_zero(i64 %unused, i64 %a, i64 %b) {
20+
; CHECK-LABEL: fshl_i64_by_zero:
21+
; CHECK: // %bb.0:
22+
; CHECK-NEXT: mov x0, x1
23+
; CHECK-NEXT: ret
24+
%r = call i64 @llvm.fshl.i64(i64 %a, i64 %b, i64 zeroinitializer)
25+
ret i64 %r
26+
}
27+
28+
define i32 @fshr_i32_by_zero(i32 %unused, i32 %a, i32 %b) {
29+
; CHECK-LABEL: fshr_i32_by_zero:
30+
; CHECK: // %bb.0:
31+
; CHECK-NEXT: mov w0, w2
32+
; CHECK-NEXT: ret
33+
%r = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 zeroinitializer)
34+
ret i32 %r
35+
}
36+
37+
define i64 @fshr_i64_by_zero(i64 %unused, i64 %a, i64 %b) {
38+
; CHECK-LABEL: fshr_i64_by_zero:
39+
; CHECK: // %bb.0:
40+
; CHECK-NEXT: mov x0, x2
41+
; CHECK-NEXT: ret
42+
%r = call i64 @llvm.fshr.i64(i64 %a, i64 %b, i64 zeroinitializer)
43+
ret i64 %r
44+
}

0 commit comments

Comments
 (0)