llvm.org GIT mirror llvm / 753cb24
[DemandedBits] Add support for funnel shifts Add support for funnel shifts to the DemandedBits analysis. The demanded bits of the first two operands can be determined if the shift amount is constant. The demanded bits of the third operand (shift amount) can be determined if the bitwidth is a power of two. This is basically the same functionality as implemented in D54869 and D54478, but for DemandedBits rather than InstCombine. Differential Revision: https://reviews.llvm.org/D54876 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347561 91177308-0d34-0410-b5e6-96231b3b80d8 Nikita Popov 11 months ago
2 changed file(s) with 100 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
141141 std::min(BitWidth, Known.countMaxTrailingZeros()+1));
142142 }
143143 break;
144 case Intrinsic::fshl:
145 case Intrinsic::fshr:
146 if (OperandNo == 2) {
147 // Shift amount is modulo the bitwidth. For powers of two we have
148 // SA % BW == SA & (BW - 1).
149 if (isPowerOf2_32(BitWidth))
150 AB = BitWidth - 1;
151 } else if (auto *SA = dyn_cast(II->getOperand(2))) {
152 // TODO: Support vectors.
153 // Normalize to funnel shift left. APInt shifts of BitWidth are well-
154 // defined, so no need to special-case zero shifts here.
155 uint64_t ShiftAmt = SA->getValue().urem(BitWidth);
156 if (II->getIntrinsicID() == Intrinsic::fshr)
157 ShiftAmt = BitWidth - ShiftAmt;
158
159 if (OperandNo == 0)
160 AB = AOut.lshr(ShiftAmt);
161 else if (OperandNo == 1)
162 AB = AOut.shl(BitWidth - ShiftAmt);
163 }
164 break;
144165 }
145166 break;
146167 case Instruction::Add:
2222 }
2323 declare i32 @llvm.bitreverse.i32(i32)
2424
25 ; Funnel shifts
26 declare i32 @llvm.fshl.i32(i32, i32, i32)
27 declare i33 @llvm.fshr.i33(i33, i33, i33)
28
29 ; CHECK-DAG: DemandedBits: 0xff for %x2 = or i32 %x, 1
30 ; CHECK-DAG: DemandedBits: 0xff000000 for %y2 = or i32 %y, 1
31 ; CHECK-DAG: DemandedBits: 0xffff for %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 8)
32 ; CHECK-DAG: DemandedBits: 0xffffffff for %r = and i32 %z, 65535
33 define i32 @test_fshl(i32 %x, i32 %y) {
34 %x2 = or i32 %x, 1
35 %y2 = or i32 %y, 1
36 %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 8)
37 %r = and i32 %z, 65535
38 ret i32 %r
39 }
40
41 ; CHECK-DAG: DemandedBits: 0xff for %x2 = or i33 %x, 1
42 ; CHECK-DAG: DemandedBits: 0x1fe000000 for %y2 = or i33 %y, 1
43 ; CHECK-DAG: DemandedBits: 0xffff for %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 25)
44 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %r = and i33 %z, 65535
45 define i33 @test_fshr(i33 %x, i33 %y) {
46 %x2 = or i33 %x, 1
47 %y2 = or i33 %y, 1
48 %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 25)
49 %r = and i33 %z, 65535
50 ret i33 %r
51 }
52
53 ; CHECK-DAG: DemandedBits: 0xffff for %x2 = or i32 %x, 1
54 ; CHECK-DAG: DemandedBits: 0x0 for %y2 = or i32 %y, 1
55 ; CHECK-DAG: DemandedBits: 0xffff for %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 0)
56 ; CHECK-DAG: DemandedBits: 0xffffffff for %r = and i32 %z, 65535
57 define i32 @test_fshl_zero_shift(i32 %x, i32 %y) {
58 %x2 = or i32 %x, 1
59 %y2 = or i32 %y, 1
60 %z = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 0)
61 %r = and i32 %z, 65535
62 ret i32 %r
63 }
64
65 ; CHECK-DAG: DemandedBits: 0x0 for %x2 = or i33 %x, 1
66 ; CHECK-DAG: DemandedBits: 0xffff for %y2 = or i33 %y, 1
67 ; CHECK-DAG: DemandedBits: 0xffff for %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 33)
68 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %r = and i33 %z, 65535
69 define i33 @test_fshr_full_shift(i33 %x, i33 %y) {
70 %x2 = or i33 %x, 1
71 %y2 = or i33 %y, 1
72 %z = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 33)
73 %r = and i33 %z, 65535
74 ret i33 %r
75 }
76
77 ; CHECK-DAG: DemandedBits: 0xffffffff for %x2 = or i32 %x, 1
78 ; CHECK-DAG: DemandedBits: 0xffffffff for %y2 = or i32 %y, 1
79 ; CHECK-DAG: DemandedBits: 0x1f for %z2 = or i32 %z, 1
80 ; CHECK-DAG: DemandedBits: 0xffff for %f = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 %z2)
81 ; CHECK-DAG: DemandedBits: 0xffffffff for %r = and i32 %f, 65535
82 define i32 @test_fshl_pow2_bitwidth(i32 %x, i32 %y, i32 %z) {
83 %x2 = or i32 %x, 1
84 %y2 = or i32 %y, 1
85 %z2 = or i32 %z, 1
86 %f = call i32 @llvm.fshl.i32(i32 %x2, i32 %y2, i32 %z2)
87 %r = and i32 %f, 65535
88 ret i32 %r
89 }
90
91 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %x2 = or i33 %x, 1
92 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %y2 = or i33 %y, 1
93 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %z2 = or i33 %z, 1
94 ; CHECK-DAG: DemandedBits: 0xffff for %f = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 %z2)
95 ; CHECK-DAG: DemandedBits: 0x1ffffffff for %r = and i33 %f, 65535
96 define i33 @test_fshr_non_pow2_bitwidth(i33 %x, i33 %y, i33 %z) {
97 %x2 = or i33 %x, 1
98 %y2 = or i33 %y, 1
99 %z2 = or i33 %z, 1
100 %f = call i33 @llvm.fshr.i33(i33 %x2, i33 %y2, i33 %z2)
101 %r = and i33 %f, 65535
102 ret i33 %r
103 }