Skip to content

Commit 7b03fdb

Browse files
authored
[X86] Add basic computeKnownBits support for X86ISD::BSR (#102474)
Resurrect https://reviews.llvm.org/D89214 (by @topperc) The behaviour is undefined for an input of 0, otherwise the result is the position of the most significant set bit which must be in the range [0, bitwidth-1]. So any bits above log2 of bitwidth must be 0. Fixes #74101
1 parent 1ec3313 commit 7b03fdb

10 files changed

+65
-81
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37246,6 +37246,12 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
3724637246
Known = KnownBits::mul(Known, Known2);
3724737247
break;
3724837248
}
37249+
case X86ISD::BSR:
37250+
// BSR(0) is undef, but any use of BSR already accounts for non-zero inputs.
37251+
// Similar KnownBits behaviour to CTLZ_ZERO_UNDEF.
37252+
// TODO: Bound with input known bits?
37253+
Known.Zero.setBitsFrom(Log2_32(BitWidth));
37254+
break;
3724937255
case X86ISD::SETCC:
3725037256
Known.Zero.setBitsFrom(1);
3725137257
break;

llvm/test/CodeGen/X86/combine-sub.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,13 +453,12 @@ define void @PR52032_4(ptr %p, ptr %q) {
453453
ret void
454454
}
455455

456-
; FIXME: Failure to fold add(xor(bsr(x),-32),33) -> add(or(bsr(x),-32),33) -> add(bsr(x),1)
456+
; Fold sub(32,xor(bsr(x),31)) -> add(xor(bsr(x),-32),33) -> add(or(bsr(x),-32),33) -> add(bsr(x),1)
457457
define i32 @PR74101(i32 %a0) {
458458
; CHECK-LABEL: PR74101:
459459
; CHECK: # %bb.0:
460460
; CHECK-NEXT: bsrl %edi, %eax
461-
; CHECK-NEXT: xorl $-32, %eax
462-
; CHECK-NEXT: addl $33, %eax
461+
; CHECK-NEXT: incl %eax
463462
; CHECK-NEXT: retq
464463
%lz = call i32 @llvm.ctlz.i32(i32 %a0, i1 true)
465464
%add = sub nuw nsw i32 32, %lz

llvm/test/CodeGen/X86/ctlo.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ define i64 @ctlo_i64_undef(i64 %x) {
364364
; X86-NOCMOV-NEXT: notl %eax
365365
; X86-NOCMOV-NEXT: bsrl %eax, %eax
366366
; X86-NOCMOV-NEXT: xorl $31, %eax
367-
; X86-NOCMOV-NEXT: addl $32, %eax
367+
; X86-NOCMOV-NEXT: orl $32, %eax
368368
; X86-NOCMOV-NEXT: xorl %edx, %edx
369369
; X86-NOCMOV-NEXT: retl
370370
; X86-NOCMOV-NEXT: .LBB7_1:
@@ -383,7 +383,7 @@ define i64 @ctlo_i64_undef(i64 %x) {
383383
; X86-CMOV-NEXT: xorl $31, %edx
384384
; X86-CMOV-NEXT: bsrl %eax, %eax
385385
; X86-CMOV-NEXT: xorl $31, %eax
386-
; X86-CMOV-NEXT: addl $32, %eax
386+
; X86-CMOV-NEXT: orl $32, %eax
387387
; X86-CMOV-NEXT: testl %ecx, %ecx
388388
; X86-CMOV-NEXT: cmovnel %edx, %eax
389389
; X86-CMOV-NEXT: xorl %edx, %edx

llvm/test/CodeGen/X86/ctlz.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ define i64 @ctlz_i64(i64 %x) {
145145
; X86-NOCMOV-NEXT: # %bb.2:
146146
; X86-NOCMOV-NEXT: bsrl {{[0-9]+}}(%esp), %eax
147147
; X86-NOCMOV-NEXT: xorl $31, %eax
148-
; X86-NOCMOV-NEXT: addl $32, %eax
148+
; X86-NOCMOV-NEXT: orl $32, %eax
149149
; X86-NOCMOV-NEXT: xorl %edx, %edx
150150
; X86-NOCMOV-NEXT: retl
151151
; X86-NOCMOV-NEXT: .LBB3_1:
@@ -161,7 +161,7 @@ define i64 @ctlz_i64(i64 %x) {
161161
; X86-CMOV-NEXT: xorl $31, %edx
162162
; X86-CMOV-NEXT: bsrl {{[0-9]+}}(%esp), %eax
163163
; X86-CMOV-NEXT: xorl $31, %eax
164-
; X86-CMOV-NEXT: addl $32, %eax
164+
; X86-CMOV-NEXT: orl $32, %eax
165165
; X86-CMOV-NEXT: testl %ecx, %ecx
166166
; X86-CMOV-NEXT: cmovnel %edx, %eax
167167
; X86-CMOV-NEXT: xorl %edx, %edx
@@ -1126,7 +1126,7 @@ define i64 @ctlz_xor63_i64_true(i64 %x) {
11261126
; X86-NOCMOV-NEXT: # %bb.2:
11271127
; X86-NOCMOV-NEXT: bsrl {{[0-9]+}}(%esp), %eax
11281128
; X86-NOCMOV-NEXT: xorl $31, %eax
1129-
; X86-NOCMOV-NEXT: addl $32, %eax
1129+
; X86-NOCMOV-NEXT: orl $32, %eax
11301130
; X86-NOCMOV-NEXT: jmp .LBB19_3
11311131
; X86-NOCMOV-NEXT: .LBB19_1:
11321132
; X86-NOCMOV-NEXT: bsrl %eax, %eax
@@ -1143,7 +1143,7 @@ define i64 @ctlz_xor63_i64_true(i64 %x) {
11431143
; X86-CMOV-NEXT: xorl $31, %edx
11441144
; X86-CMOV-NEXT: bsrl {{[0-9]+}}(%esp), %eax
11451145
; X86-CMOV-NEXT: xorl $31, %eax
1146-
; X86-CMOV-NEXT: addl $32, %eax
1146+
; X86-CMOV-NEXT: orl $32, %eax
11471147
; X86-CMOV-NEXT: testl %ecx, %ecx
11481148
; X86-CMOV-NEXT: cmovnel %edx, %eax
11491149
; X86-CMOV-NEXT: xorl $63, %eax

llvm/test/CodeGen/X86/div-rem-pair-recomposition-signed.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,19 +234,19 @@ define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
234234
; X86-NEXT: xorl $31, %edx
235235
; X86-NEXT: bsrl %ebx, %ecx
236236
; X86-NEXT: xorl $31, %ecx
237-
; X86-NEXT: addl $32, %ecx
237+
; X86-NEXT: orl $32, %ecx
238238
; X86-NEXT: testl %esi, %esi
239239
; X86-NEXT: cmovnel %edx, %ecx
240240
; X86-NEXT: bsrl %ebp, %edx
241241
; X86-NEXT: xorl $31, %edx
242242
; X86-NEXT: movl %edi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
243243
; X86-NEXT: bsrl %edi, %edi
244244
; X86-NEXT: xorl $31, %edi
245-
; X86-NEXT: addl $32, %edi
245+
; X86-NEXT: orl $32, %edi
246246
; X86-NEXT: movl %ebp, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
247247
; X86-NEXT: testl %ebp, %ebp
248248
; X86-NEXT: cmovnel %edx, %edi
249-
; X86-NEXT: addl $64, %edi
249+
; X86-NEXT: orl $64, %edi
250250
; X86-NEXT: movl %ebx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
251251
; X86-NEXT: movl %ebx, %edx
252252
; X86-NEXT: movl %esi, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
@@ -258,18 +258,18 @@ define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
258258
; X86-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %ebp # 4-byte Reload
259259
; X86-NEXT: bsrl %ebp, %ecx
260260
; X86-NEXT: xorl $31, %ecx
261-
; X86-NEXT: addl $32, %ecx
261+
; X86-NEXT: orl $32, %ecx
262262
; X86-NEXT: testl %ebx, %ebx
263263
; X86-NEXT: cmovnel %edx, %ecx
264264
; X86-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
265265
; X86-NEXT: bsrl %eax, %esi
266266
; X86-NEXT: xorl $31, %esi
267267
; X86-NEXT: bsrl {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload
268268
; X86-NEXT: xorl $31, %edx
269-
; X86-NEXT: addl $32, %edx
269+
; X86-NEXT: orl $32, %edx
270270
; X86-NEXT: testl %eax, %eax
271271
; X86-NEXT: cmovnel %esi, %edx
272-
; X86-NEXT: addl $64, %edx
272+
; X86-NEXT: orl $64, %edx
273273
; X86-NEXT: movl %ebp, %esi
274274
; X86-NEXT: orl %ebx, %esi
275275
; X86-NEXT: cmovnel %ecx, %edx

llvm/test/CodeGen/X86/div-rem-pair-recomposition-unsigned.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
199199
; X86-NEXT: xorl $31, %edx
200200
; X86-NEXT: bsrl %esi, %ecx
201201
; X86-NEXT: xorl $31, %ecx
202-
; X86-NEXT: addl $32, %ecx
202+
; X86-NEXT: orl $32, %ecx
203203
; X86-NEXT: testl %edi, %edi
204204
; X86-NEXT: movl %edi, %ebx
205205
; X86-NEXT: cmovnel %edx, %ecx
@@ -210,10 +210,10 @@ define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
210210
; X86-NEXT: movl %esi, %edi
211211
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
212212
; X86-NEXT: xorl $31, %ebp
213-
; X86-NEXT: addl $32, %ebp
213+
; X86-NEXT: orl $32, %ebp
214214
; X86-NEXT: testl %eax, %eax
215215
; X86-NEXT: cmovnel %edx, %ebp
216-
; X86-NEXT: addl $64, %ebp
216+
; X86-NEXT: orl $64, %ebp
217217
; X86-NEXT: movl %edi, %edx
218218
; X86-NEXT: orl %ebx, %edx
219219
; X86-NEXT: cmovnel %ecx, %ebp
@@ -223,18 +223,18 @@ define i128 @scalar_i128(i128 %x, i128 %y, ptr %divdst) nounwind {
223223
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
224224
; X86-NEXT: bsrl %eax, %ecx
225225
; X86-NEXT: xorl $31, %ecx
226-
; X86-NEXT: addl $32, %ecx
226+
; X86-NEXT: orl $32, %ecx
227227
; X86-NEXT: testl %esi, %esi
228228
; X86-NEXT: cmovnel %edx, %ecx
229229
; X86-NEXT: movl {{[0-9]+}}(%esp), %edi
230230
; X86-NEXT: bsrl %edi, %esi
231231
; X86-NEXT: xorl $31, %esi
232232
; X86-NEXT: bsrl {{[0-9]+}}(%esp), %edx
233233
; X86-NEXT: xorl $31, %edx
234-
; X86-NEXT: addl $32, %edx
234+
; X86-NEXT: orl $32, %edx
235235
; X86-NEXT: testl %edi, %edi
236236
; X86-NEXT: cmovnel %esi, %edx
237-
; X86-NEXT: addl $64, %edx
237+
; X86-NEXT: orl $64, %edx
238238
; X86-NEXT: orl %ebx, %eax
239239
; X86-NEXT: cmovnel %ecx, %edx
240240
; X86-NEXT: subl %edx, %ebp

llvm/test/CodeGen/X86/lzcnt-cmp.ll

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ define i1 @lshr_ctlz_cmpeq_one_i64(i64 %in) nounwind {
1919
; X64-BSR-NEXT: # %bb.2: # %cond.false
2020
; X64-BSR-NEXT: bsrq %rdi, %rax
2121
; X64-BSR-NEXT: xorq $63, %rax
22-
; X64-BSR-NEXT: jmp .LBB0_3
22+
; X64-BSR-NEXT: shrl $6, %eax
23+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
24+
; X64-BSR-NEXT: retq
2325
; X64-BSR-NEXT: .LBB0_1:
2426
; X64-BSR-NEXT: movl $64, %eax
25-
; X64-BSR-NEXT: .LBB0_3: # %cond.end
26-
; X64-BSR-NEXT: shrq $6, %rax
27-
; X64-BSR-NEXT: cmpq $1, %rax
28-
; X64-BSR-NEXT: sete %al
27+
; X64-BSR-NEXT: shrl $6, %eax
28+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
2929
; X64-BSR-NEXT: retq
3030
;
3131
; X64-LZCNT-LABEL: lshr_ctlz_cmpeq_one_i64:
@@ -43,15 +43,6 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) nounwind {
4343
; X86-BSR-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
4444
; X86-BSR: # %bb.0:
4545
; X86-BSR-NEXT: xorl %eax, %eax
46-
; X86-BSR-NEXT: cmpl $0, {{[0-9]+}}(%esp)
47-
; X86-BSR-NEXT: jne .LBB1_2
48-
; X86-BSR-NEXT: # %bb.1:
49-
; X86-BSR-NEXT: bsrl {{[0-9]+}}(%esp), %eax
50-
; X86-BSR-NEXT: xorl $31, %eax
51-
; X86-BSR-NEXT: addl $32, %eax
52-
; X86-BSR-NEXT: .LBB1_2:
53-
; X86-BSR-NEXT: shrl $6, %eax
54-
; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
5546
; X86-BSR-NEXT: retl
5647
;
5748
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
@@ -67,9 +58,7 @@ define i1 @lshr_ctlz_undef_cmpeq_one_i64(i64 %in) nounwind {
6758
;
6859
; X64-BSR-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
6960
; X64-BSR: # %bb.0:
70-
; X64-BSR-NEXT: bsrq %rdi, %rax
71-
; X64-BSR-NEXT: shrl $6, %eax
72-
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
61+
; X64-BSR-NEXT: xorl %eax, %eax
7362
; X64-BSR-NEXT: retq
7463
;
7564
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpeq_one_i64:
@@ -99,12 +88,13 @@ define i1 @lshr_ctlz_cmpne_zero_i64(i64 %in) nounwind {
9988
; X64-BSR-NEXT: # %bb.2: # %cond.false
10089
; X64-BSR-NEXT: bsrq %rdi, %rax
10190
; X64-BSR-NEXT: xorq $63, %rax
102-
; X64-BSR-NEXT: jmp .LBB2_3
91+
; X64-BSR-NEXT: shrl $6, %eax
92+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
93+
; X64-BSR-NEXT: retq
10394
; X64-BSR-NEXT: .LBB2_1:
10495
; X64-BSR-NEXT: movl $64, %eax
105-
; X64-BSR-NEXT: .LBB2_3: # %cond.end
106-
; X64-BSR-NEXT: testq $-64, %rax
107-
; X64-BSR-NEXT: setne %al
96+
; X64-BSR-NEXT: shrl $6, %eax
97+
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
10898
; X64-BSR-NEXT: retq
10999
;
110100
; X64-LZCNT-LABEL: lshr_ctlz_cmpne_zero_i64:
@@ -122,15 +112,6 @@ define i1 @lshr_ctlz_undef_cmpne_zero_i64(i64 %in) nounwind {
122112
; X86-BSR-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
123113
; X86-BSR: # %bb.0:
124114
; X86-BSR-NEXT: xorl %eax, %eax
125-
; X86-BSR-NEXT: cmpl $0, {{[0-9]+}}(%esp)
126-
; X86-BSR-NEXT: jne .LBB3_2
127-
; X86-BSR-NEXT: # %bb.1:
128-
; X86-BSR-NEXT: bsrl {{[0-9]+}}(%esp), %eax
129-
; X86-BSR-NEXT: xorl $31, %eax
130-
; X86-BSR-NEXT: addl $32, %eax
131-
; X86-BSR-NEXT: .LBB3_2:
132-
; X86-BSR-NEXT: shrl $6, %eax
133-
; X86-BSR-NEXT: # kill: def $al killed $al killed $eax
134115
; X86-BSR-NEXT: retl
135116
;
136117
; X86-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
@@ -146,9 +127,7 @@ define i1 @lshr_ctlz_undef_cmpne_zero_i64(i64 %in) nounwind {
146127
;
147128
; X64-BSR-LABEL: lshr_ctlz_undef_cmpne_zero_i64:
148129
; X64-BSR: # %bb.0:
149-
; X64-BSR-NEXT: bsrq %rdi, %rax
150-
; X64-BSR-NEXT: shrl $6, %eax
151-
; X64-BSR-NEXT: # kill: def $al killed $al killed $rax
130+
; X64-BSR-NEXT: xorl %eax, %eax
152131
; X64-BSR-NEXT: retq
153132
;
154133
; X64-LZCNT-LABEL: lshr_ctlz_undef_cmpne_zero_i64:

llvm/test/CodeGen/X86/pr38539.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ define void @f() nounwind {
5252
; X86-NEXT: # %bb.2: # %BB_udiv-special-cases
5353
; X86-NEXT: bsrl %edx, %eax
5454
; X86-NEXT: xorl $31, %eax
55-
; X86-NEXT: addl $32, %eax
55+
; X86-NEXT: orl $32, %eax
5656
; X86-NEXT: jmp .LBB0_3
5757
; X86-NEXT: .LBB0_1:
5858
; X86-NEXT: bsrl %ecx, %eax

llvm/test/CodeGen/X86/pr40090.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define i64 @foo(i64 %x, i64 %y) {
55
; CHECK-LABEL: foo:
66
; CHECK: # %bb.0:
77
; CHECK-NEXT: bsrq %rdi, %rax
8-
; CHECK-NEXT: xorq $64, %rax
8+
; CHECK-NEXT: orq $64, %rax
99
; CHECK-NEXT: bsrq %rsi, %rcx
1010
; CHECK-NEXT: cmoveq %rax, %rcx
1111
; CHECK-NEXT: movl $63, %eax

0 commit comments

Comments
 (0)