Skip to content

Commit a0bd2cf

Browse files
committed
[X86] Allow speculative BSR/BSF instructions on targets with CMOV
1 parent 21de049 commit a0bd2cf

23 files changed

+1913
-3239
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3239,14 +3239,14 @@ bool X86TargetLowering::shouldFormOverflowOp(unsigned Opcode, EVT VT,
32393239

32403240
bool X86TargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
32413241
// Speculate cttz only if we can directly use TZCNT or can promote to i32/i64.
3242-
return Subtarget.hasBMI() ||
3242+
return Subtarget.hasBMI() || Subtarget.canUseCMOV() ||
32433243
(!Ty->isVectorTy() &&
32443244
Ty->getScalarSizeInBits() < (Subtarget.is64Bit() ? 64u : 32u));
32453245
}
32463246

32473247
bool X86TargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
32483248
// Speculate ctlz only if we can directly use LZCNT.
3249-
return Subtarget.hasLZCNT();
3249+
return Subtarget.hasLZCNT() || Subtarget.canUseCMOV();
32503250
}
32513251

32523252
bool X86TargetLowering::ShouldShrinkFPConstant(EVT VT) const {

llvm/test/Analysis/CostModel/X86/ctlz-codesize.ll

+12-28
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@ declare i16 @llvm.ctlz.i16(i16, i1)
1616
declare i8 @llvm.ctlz.i8(i8, i1)
1717

1818
define i64 @var_ctlz_i64(i64 %a) {
19-
; NOLZCNT-LABEL: 'var_ctlz_i64'
20-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
22-
;
23-
; LZCNT-LABEL: 'var_ctlz_i64'
24-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
25-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
19+
; CHECK-LABEL: 'var_ctlz_i64'
20+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
2622
;
2723
%ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 0)
2824
ret i64 %ctlz
@@ -38,13 +34,9 @@ define i64 @var_ctlz_i64u(i64 %a) {
3834
}
3935

4036
define i32 @var_ctlz_i32(i32 %a) {
41-
; NOLZCNT-LABEL: 'var_ctlz_i32'
42-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
43-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
44-
;
45-
; LZCNT-LABEL: 'var_ctlz_i32'
46-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
47-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
37+
; CHECK-LABEL: 'var_ctlz_i32'
38+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
39+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
4840
;
4941
%ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
5042
ret i32 %ctlz
@@ -60,13 +52,9 @@ define i32 @var_ctlz_i32u(i32 %a) {
6052
}
6153

6254
define i16 @var_ctlz_i16(i16 %a) {
63-
; NOLZCNT-LABEL: 'var_ctlz_i16'
64-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
65-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
66-
;
67-
; LZCNT-LABEL: 'var_ctlz_i16'
68-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
69-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
55+
; CHECK-LABEL: 'var_ctlz_i16'
56+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
57+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
7058
;
7159
%ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 0)
7260
ret i16 %ctlz
@@ -86,13 +74,9 @@ define i16 @var_ctlz_i16u(i16 %a) {
8674
}
8775

8876
define i8 @var_ctlz_i8(i8 %a) {
89-
; NOLZCNT-LABEL: 'var_ctlz_i8'
90-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
91-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
92-
;
93-
; LZCNT-LABEL: 'var_ctlz_i8'
94-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
95-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
77+
; CHECK-LABEL: 'var_ctlz_i8'
78+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
79+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
9680
;
9781
%ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 0)
9882
ret i8 %ctlz

llvm/test/Analysis/CostModel/X86/ctlz-latency.ll

+12-28
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@ declare i16 @llvm.ctlz.i16(i16, i1)
1616
declare i8 @llvm.ctlz.i8(i8, i1)
1717

1818
define i64 @var_ctlz_i64(i64 %a) {
19-
; NOLZCNT-LABEL: 'var_ctlz_i64'
20-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
22-
;
23-
; LZCNT-LABEL: 'var_ctlz_i64'
24-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
25-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
19+
; CHECK-LABEL: 'var_ctlz_i64'
20+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
2622
;
2723
%ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 0)
2824
ret i64 %ctlz
@@ -38,13 +34,9 @@ define i64 @var_ctlz_i64u(i64 %a) {
3834
}
3935

4036
define i32 @var_ctlz_i32(i32 %a) {
41-
; NOLZCNT-LABEL: 'var_ctlz_i32'
42-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
43-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
44-
;
45-
; LZCNT-LABEL: 'var_ctlz_i32'
46-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
47-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
37+
; CHECK-LABEL: 'var_ctlz_i32'
38+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
39+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
4840
;
4941
%ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
5042
ret i32 %ctlz
@@ -60,13 +52,9 @@ define i32 @var_ctlz_i32u(i32 %a) {
6052
}
6153

6254
define i16 @var_ctlz_i16(i16 %a) {
63-
; NOLZCNT-LABEL: 'var_ctlz_i16'
64-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
65-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
66-
;
67-
; LZCNT-LABEL: 'var_ctlz_i16'
68-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
69-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
55+
; CHECK-LABEL: 'var_ctlz_i16'
56+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
57+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
7058
;
7159
%ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 0)
7260
ret i16 %ctlz
@@ -86,13 +74,9 @@ define i16 @var_ctlz_i16u(i16 %a) {
8674
}
8775

8876
define i8 @var_ctlz_i8(i8 %a) {
89-
; NOLZCNT-LABEL: 'var_ctlz_i8'
90-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
91-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
92-
;
93-
; LZCNT-LABEL: 'var_ctlz_i8'
94-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
95-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
77+
; CHECK-LABEL: 'var_ctlz_i8'
78+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
79+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
9680
;
9781
%ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 0)
9882
ret i8 %ctlz

llvm/test/Analysis/CostModel/X86/ctlz-sizelatency.ll

+12-28
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@ declare i16 @llvm.ctlz.i16(i16, i1)
1616
declare i8 @llvm.ctlz.i8(i8, i1)
1717

1818
define i64 @var_ctlz_i64(i64 %a) {
19-
; NOLZCNT-LABEL: 'var_ctlz_i64'
20-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
22-
;
23-
; LZCNT-LABEL: 'var_ctlz_i64'
24-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
25-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
19+
; CHECK-LABEL: 'var_ctlz_i64'
20+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 false)
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %ctlz
2622
;
2723
%ctlz = call i64 @llvm.ctlz.i64(i64 %a, i1 0)
2824
ret i64 %ctlz
@@ -38,13 +34,9 @@ define i64 @var_ctlz_i64u(i64 %a) {
3834
}
3935

4036
define i32 @var_ctlz_i32(i32 %a) {
41-
; NOLZCNT-LABEL: 'var_ctlz_i32'
42-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
43-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
44-
;
45-
; LZCNT-LABEL: 'var_ctlz_i32'
46-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
47-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
37+
; CHECK-LABEL: 'var_ctlz_i32'
38+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 false)
39+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %ctlz
4840
;
4941
%ctlz = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
5042
ret i32 %ctlz
@@ -60,13 +52,9 @@ define i32 @var_ctlz_i32u(i32 %a) {
6052
}
6153

6254
define i16 @var_ctlz_i16(i16 %a) {
63-
; NOLZCNT-LABEL: 'var_ctlz_i16'
64-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
65-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
66-
;
67-
; LZCNT-LABEL: 'var_ctlz_i16'
68-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
69-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
55+
; CHECK-LABEL: 'var_ctlz_i16'
56+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 false)
57+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %ctlz
7058
;
7159
%ctlz = call i16 @llvm.ctlz.i16(i16 %a, i1 0)
7260
ret i16 %ctlz
@@ -86,13 +74,9 @@ define i16 @var_ctlz_i16u(i16 %a) {
8674
}
8775

8876
define i8 @var_ctlz_i8(i8 %a) {
89-
; NOLZCNT-LABEL: 'var_ctlz_i8'
90-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
91-
; NOLZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
92-
;
93-
; LZCNT-LABEL: 'var_ctlz_i8'
94-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
95-
; LZCNT-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
77+
; CHECK-LABEL: 'var_ctlz_i8'
78+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 false)
79+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %ctlz
9680
;
9781
%ctlz = call i8 @llvm.ctlz.i8(i8 %a, i1 0)
9882
ret i8 %ctlz

llvm/test/Analysis/CostModel/X86/cttz-codesize.ll

+5-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ declare i16 @llvm.cttz.i16(i16, i1)
1717
declare i8 @llvm.cttz.i8(i8, i1)
1818

1919
define i64 @var_cttz_i64(i64 %a) {
20-
; NOBMI-LABEL: 'var_cttz_i64'
21-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
23-
;
24-
; BMI-LABEL: 'var_cttz_i64'
25-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
26-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
20+
; CHECK-LABEL: 'var_cttz_i64'
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
2723
;
2824
%cttz = call i64 @llvm.cttz.i64(i64 %a, i1 0)
2925
ret i64 %cttz
@@ -788,3 +784,5 @@ define <64 x i8> @var_cttz_v64i8u(<64 x i8> %a) {
788784
%cttz = call <64 x i8> @llvm.cttz.v64i8(<64 x i8> %a, i1 1)
789785
ret <64 x i8> %cttz
790786
}
787+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
788+
; BMI: {{.*}}

llvm/test/Analysis/CostModel/X86/cttz-latency.ll

+3-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ declare i16 @llvm.cttz.i16(i16, i1)
1717
declare i8 @llvm.cttz.i8(i8, i1)
1818

1919
define i64 @var_cttz_i64(i64 %a) {
20-
; NOBMI-LABEL: 'var_cttz_i64'
21-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
23-
;
24-
; BMI-LABEL: 'var_cttz_i64'
25-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
26-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
20+
; CHECK-LABEL: 'var_cttz_i64'
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
2723
;
2824
%cttz = call i64 @llvm.cttz.i64(i64 %a, i1 0)
2925
ret i64 %cttz

llvm/test/Analysis/CostModel/X86/cttz-sizelatency.ll

+5-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,9 @@ declare i16 @llvm.cttz.i16(i16, i1)
1717
declare i8 @llvm.cttz.i8(i8, i1)
1818

1919
define i64 @var_cttz_i64(i64 %a) {
20-
; NOBMI-LABEL: 'var_cttz_i64'
21-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22-
; NOBMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
23-
;
24-
; BMI-LABEL: 'var_cttz_i64'
25-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
26-
; BMI-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
20+
; CHECK-LABEL: 'var_cttz_i64'
21+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %cttz = call i64 @llvm.cttz.i64(i64 %a, i1 false)
22+
; CHECK-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %cttz
2723
;
2824
%cttz = call i64 @llvm.cttz.i64(i64 %a, i1 0)
2925
ret i64 %cttz
@@ -772,3 +768,5 @@ define <64 x i8> @var_cttz_v64i8u(<64 x i8> %a) {
772768
%cttz = call <64 x i8> @llvm.cttz.v64i8(<64 x i8> %a, i1 1)
773769
ret <64 x i8> %cttz
774770
}
771+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
772+
; BMI: {{.*}}

llvm/test/CodeGen/X86/atomic-bit-test.ll

-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,6 @@ define i32 @split_hoist_and(i32 %0) nounwind {
582582
; X64-NEXT: lock btsl $3, v32(%rip)
583583
; X64-NEXT: setb %al
584584
; X64-NEXT: shll $3, %eax
585-
; X64-NEXT: testl %edi, %edi
586585
; X64-NEXT: retq
587586
%2 = atomicrmw or ptr @v32, i32 8 monotonic, align 4
588587
%3 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)

llvm/test/CodeGen/X86/bit_ceil.ll

+17-36
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,12 @@
88
define i32 @bit_ceil_i32(i32 %x) {
99
; NOBMI-LABEL: bit_ceil_i32:
1010
; NOBMI: # %bb.0:
11-
; NOBMI-NEXT: movl %edi, %eax
12-
; NOBMI-NEXT: decl %eax
13-
; NOBMI-NEXT: je .LBB0_1
14-
; NOBMI-NEXT: # %bb.2: # %cond.false
15-
; NOBMI-NEXT: bsrl %eax, %ecx
11+
; NOBMI-NEXT: # kill: def $edi killed $edi def $rdi
12+
; NOBMI-NEXT: leal -1(%rdi), %eax
13+
; NOBMI-NEXT: bsrl %eax, %eax
14+
; NOBMI-NEXT: movl $63, %ecx
15+
; NOBMI-NEXT: cmovnel %eax, %ecx
1616
; NOBMI-NEXT: xorl $31, %ecx
17-
; NOBMI-NEXT: jmp .LBB0_3
18-
; NOBMI-NEXT: .LBB0_1:
19-
; NOBMI-NEXT: movl $32, %ecx
20-
; NOBMI-NEXT: .LBB0_3: # %cond.end
2117
; NOBMI-NEXT: negb %cl
2218
; NOBMI-NEXT: movl $1, %edx
2319
; NOBMI-NEXT: movl $1, %eax
@@ -51,15 +47,10 @@ define i32 @bit_ceil_i32(i32 %x) {
5147
define i32 @bit_ceil_i32_plus1(i32 noundef %x) {
5248
; NOBMI-LABEL: bit_ceil_i32_plus1:
5349
; NOBMI: # %bb.0: # %entry
54-
; NOBMI-NEXT: testl %edi, %edi
55-
; NOBMI-NEXT: je .LBB1_1
56-
; NOBMI-NEXT: # %bb.2: # %cond.false
57-
; NOBMI-NEXT: bsrl %edi, %ecx
50+
; NOBMI-NEXT: bsrl %edi, %eax
51+
; NOBMI-NEXT: movl $63, %ecx
52+
; NOBMI-NEXT: cmovnel %eax, %ecx
5853
; NOBMI-NEXT: xorl $31, %ecx
59-
; NOBMI-NEXT: jmp .LBB1_3
60-
; NOBMI-NEXT: .LBB1_1:
61-
; NOBMI-NEXT: movl $32, %ecx
62-
; NOBMI-NEXT: .LBB1_3: # %cond.end
6354
; NOBMI-NEXT: negb %cl
6455
; NOBMI-NEXT: movl $1, %edx
6556
; NOBMI-NEXT: movl $1, %eax
@@ -94,16 +85,11 @@ entry:
9485
define i64 @bit_ceil_i64(i64 %x) {
9586
; NOBMI-LABEL: bit_ceil_i64:
9687
; NOBMI: # %bb.0:
97-
; NOBMI-NEXT: movq %rdi, %rax
98-
; NOBMI-NEXT: decq %rax
99-
; NOBMI-NEXT: je .LBB2_1
100-
; NOBMI-NEXT: # %bb.2: # %cond.false
101-
; NOBMI-NEXT: bsrq %rax, %rcx
102-
; NOBMI-NEXT: xorq $63, %rcx
103-
; NOBMI-NEXT: jmp .LBB2_3
104-
; NOBMI-NEXT: .LBB2_1:
105-
; NOBMI-NEXT: movl $64, %ecx
106-
; NOBMI-NEXT: .LBB2_3: # %cond.end
88+
; NOBMI-NEXT: leaq -1(%rdi), %rax
89+
; NOBMI-NEXT: bsrq %rax, %rax
90+
; NOBMI-NEXT: movl $127, %ecx
91+
; NOBMI-NEXT: cmovneq %rax, %rcx
92+
; NOBMI-NEXT: xorl $63, %ecx
10793
; NOBMI-NEXT: negb %cl
10894
; NOBMI-NEXT: movl $1, %edx
10995
; NOBMI-NEXT: movl $1, %eax
@@ -136,15 +122,10 @@ define i64 @bit_ceil_i64(i64 %x) {
136122
define i64 @bit_ceil_i64_plus1(i64 noundef %x) {
137123
; NOBMI-LABEL: bit_ceil_i64_plus1:
138124
; NOBMI: # %bb.0: # %entry
139-
; NOBMI-NEXT: testq %rdi, %rdi
140-
; NOBMI-NEXT: je .LBB3_1
141-
; NOBMI-NEXT: # %bb.2: # %cond.false
142-
; NOBMI-NEXT: bsrq %rdi, %rcx
143-
; NOBMI-NEXT: xorq $63, %rcx
144-
; NOBMI-NEXT: jmp .LBB3_3
145-
; NOBMI-NEXT: .LBB3_1:
146-
; NOBMI-NEXT: movl $64, %ecx
147-
; NOBMI-NEXT: .LBB3_3: # %cond.end
125+
; NOBMI-NEXT: bsrq %rdi, %rax
126+
; NOBMI-NEXT: movl $127, %ecx
127+
; NOBMI-NEXT: cmovneq %rax, %rcx
128+
; NOBMI-NEXT: xorl $63, %ecx
148129
; NOBMI-NEXT: negb %cl
149130
; NOBMI-NEXT: movl $1, %edx
150131
; NOBMI-NEXT: movl $1, %eax

0 commit comments

Comments
 (0)