4
4
define i32 @log2_ceil_idiom (i32 %x ) {
5
5
; CHECK-LABEL: define i32 @log2_ceil_idiom(
6
6
; CHECK-SAME: i32 [[X:%.*]]) {
7
- ; CHECK-NEXT: [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true), !range [[RNG0:![0-9]+]]
8
- ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[CTLZ]], 31
9
- ; CHECK-NEXT: [[CTPOP:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
10
- ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CTPOP]], 1
11
- ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
12
- ; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
7
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1
8
+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false), !range [[RNG0:![0-9]+]]
9
+ ; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
13
10
; CHECK-NEXT: ret i32 [[RET]]
14
11
;
15
12
%ctlz = tail call i32 @llvm.ctlz.i32 (i32 %x , i1 true )
@@ -24,13 +21,10 @@ define i32 @log2_ceil_idiom(i32 %x) {
24
21
define i5 @log2_ceil_idiom_trunc (i32 %x ) {
25
22
; CHECK-LABEL: define i5 @log2_ceil_idiom_trunc(
26
23
; CHECK-SAME: i32 [[X:%.*]]) {
27
- ; CHECK-NEXT: [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true), !range [[RNG0]]
28
- ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[CTLZ]] to i5
29
- ; CHECK-NEXT: [[XOR:%.*]] = xor i5 [[TRUNC]], -1
30
- ; CHECK-NEXT: [[CTPOP:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
31
- ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CTPOP]], 1
32
- ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i5
33
- ; CHECK-NEXT: [[RET:%.*]] = add i5 [[XOR]], [[ZEXT]]
24
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1
25
+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false), !range [[RNG0]]
26
+ ; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 0, [[TMP2]]
27
+ ; CHECK-NEXT: [[RET:%.*]] = trunc i32 [[TMP3]] to i5
34
28
; CHECK-NEXT: ret i5 [[RET]]
35
29
;
36
30
%ctlz = tail call i32 @llvm.ctlz.i32 (i32 %x , i1 true )
@@ -46,13 +40,10 @@ define i5 @log2_ceil_idiom_trunc(i32 %x) {
46
40
define i64 @log2_ceil_idiom_zext (i32 %x ) {
47
41
; CHECK-LABEL: define i64 @log2_ceil_idiom_zext(
48
42
; CHECK-SAME: i32 [[X:%.*]]) {
49
- ; CHECK-NEXT: [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true), !range [[RNG0]]
50
- ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[CTLZ]], 31
51
- ; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[XOR]] to i64
52
- ; CHECK-NEXT: [[CTPOP:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
53
- ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CTPOP]], 1
54
- ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i64
55
- ; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i64 [[EXT]], [[ZEXT]]
43
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1
44
+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false), !range [[RNG0]]
45
+ ; CHECK-NEXT: [[TMP3:%.*]] = sub nuw nsw i32 32, [[TMP2]]
46
+ ; CHECK-NEXT: [[RET:%.*]] = zext i32 [[TMP3]] to i64
56
47
; CHECK-NEXT: ret i64 [[RET]]
57
48
;
58
49
%ctlz = tail call i32 @llvm.ctlz.i32 (i32 %x , i1 true )
@@ -68,12 +59,9 @@ define i64 @log2_ceil_idiom_zext(i32 %x) {
68
59
define i32 @log2_ceil_idiom_power2_test2 (i32 %x ) {
69
60
; CHECK-LABEL: define i32 @log2_ceil_idiom_power2_test2(
70
61
; CHECK-SAME: i32 [[X:%.*]]) {
71
- ; CHECK-NEXT: [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true), !range [[RNG0]]
72
- ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[CTLZ]], 31
73
- ; CHECK-NEXT: [[CTPOP:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
74
- ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CTPOP]], 1
75
- ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
76
- ; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
62
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1
63
+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false), !range [[RNG0]]
64
+ ; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
77
65
; CHECK-NEXT: ret i32 [[RET]]
78
66
;
79
67
%ctlz = tail call i32 @llvm.ctlz.i32 (i32 %x , i1 true )
@@ -88,12 +76,9 @@ define i32 @log2_ceil_idiom_power2_test2(i32 %x) {
88
76
define i32 @log2_ceil_idiom_commuted (i32 %x ) {
89
77
; CHECK-LABEL: define i32 @log2_ceil_idiom_commuted(
90
78
; CHECK-SAME: i32 [[X:%.*]]) {
91
- ; CHECK-NEXT: [[CTLZ:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true), !range [[RNG0]]
92
- ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[CTLZ]], 31
93
- ; CHECK-NEXT: [[CTPOP:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X]]), !range [[RNG0]]
94
- ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CTPOP]], 1
95
- ; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32
96
- ; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i32 [[XOR]], [[ZEXT]]
79
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -1
80
+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ctlz.i32(i32 [[TMP1]], i1 false), !range [[RNG0]]
81
+ ; CHECK-NEXT: [[RET:%.*]] = sub nuw nsw i32 32, [[TMP2]]
97
82
; CHECK-NEXT: ret i32 [[RET]]
98
83
;
99
84
%ctlz = tail call i32 @llvm.ctlz.i32 (i32 %x , i1 true )
0 commit comments