[TTI] Improved cost heuristic for cttz/ctlz calls.
[oota-llvm.git] / test / Transforms / SimplifyCFG / X86 / speculate-cttz-ctlz.ll
1 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
2 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
3 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
4
5
6 define i64 @test1(i64 %A) {
7 ; ALL-LABEL: @test1(
8 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
9 ; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
10 ; LZCNT-NEXT: select i1 [[COND]], i64 64, i64 [[CTLZ]]
11 ; BMI-NOT: select
12 ; GENERIC-NOT: select
13 ; ALL: ret
14 entry:
15   %tobool = icmp eq i64 %A, 0
16   br i1 %tobool, label %cond.end, label %cond.true
17
18 cond.true:                                        ; preds = %entry
19   %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
20   br label %cond.end
21
22 cond.end:                                         ; preds = %entry, %cond.true
23   %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
24   ret i64 %cond
25 }
26
27 define i32 @test2(i32 %A) {
28 ; ALL-LABEL: @test2(
29 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
30 ; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
31 ; LZCNT-NEXT: select i1 [[COND]], i32 32, i32 [[CTLZ]]
32 ; BMI-NOT: select
33 ; GENERIC-NOT: select
34 ; ALL: ret
35 entry:
36   %tobool = icmp eq i32 %A, 0
37   br i1 %tobool, label %cond.end, label %cond.true
38
39 cond.true:                                        ; preds = %entry
40   %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
41   br label %cond.end
42
43 cond.end:                                         ; preds = %entry, %cond.true
44   %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
45   ret i32 %cond
46 }
47
48
49 define signext i16 @test3(i16 signext %A) {
50 ; ALL-LABEL: @test3(
51 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
52 ; ALL: [[CTLZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
53 ; LZCNT-NEXT: select i1 [[COND]], i16 16, i16 [[CTLZ]]
54 ; BMI-NOT: select
55 ; GENERIC-NOT: select
56 ; ALL: ret
57 entry:
58   %tobool = icmp eq i16 %A, 0
59   br i1 %tobool, label %cond.end, label %cond.true
60
61 cond.true:                                        ; preds = %entry
62   %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
63   br label %cond.end
64
65 cond.end:                                         ; preds = %entry, %cond.true
66   %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
67   ret i16 %cond
68 }
69
70
71 define i64 @test1b(i64 %A) {
72 ; ALL-LABEL: @test1b(
73 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i64 %A, 0
74 ; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
75 ; BMI-NEXT: select i1 [[COND]], i64 64, i64 [[CTTZ]]
76 ; LZCNT-NOT: select
77 ; GENERIC-NOT: select
78 ; ALL: ret
79 entry:
80   %tobool = icmp eq i64 %A, 0
81   br i1 %tobool, label %cond.end, label %cond.true
82
83 cond.true:                                        ; preds = %entry
84   %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
85   br label %cond.end
86
87 cond.end:                                         ; preds = %entry, %cond.true
88   %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
89   ret i64 %cond
90 }
91
92
93 define i32 @test2b(i32 %A) {
94 ; ALL-LABEL: @test2b(
95 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i32 %A, 0
96 ; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
97 ; BMI-NEXT: select i1 [[COND]], i32 32, i32 [[CTTZ]]
98 ; LZCNT-NOT: select
99 ; GENERIC-NOT: select
100 ; ALL: ret
101 entry:
102   %tobool = icmp eq i32 %A, 0
103   br i1 %tobool, label %cond.end, label %cond.true
104
105 cond.true:                                        ; preds = %entry
106   %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
107   br label %cond.end
108
109 cond.end:                                         ; preds = %entry, %cond.true
110   %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
111   ret i32 %cond
112 }
113
114
115 define signext i16 @test3b(i16 signext %A) {
116 ; ALL-LABEL: @test3b(
117 ; ALL: [[COND:%[A-Za-z0-9]+]] = icmp eq i16 %A, 0
118 ; ALL: [[CTTZ:%[A-Za-z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
119 ; BMI-NEXT: select i1 [[COND]], i16 16, i16 [[CTTZ]]
120 ; LZCNT-NOT: select
121 ; GENERIC-NOT: select
122 ; ALL: ret
123 entry:
124   %tobool = icmp eq i16 %A, 0
125   br i1 %tobool, label %cond.end, label %cond.true
126
127 cond.true:                                        ; preds = %entry
128   %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
129   br label %cond.end
130
131 cond.end:                                         ; preds = %entry, %cond.true
132   %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
133   ret i16 %cond
134 }
135
136 declare i64 @llvm.ctlz.i64(i64, i1)
137 declare i32 @llvm.ctlz.i32(i32, i1)
138 declare i16 @llvm.ctlz.i16(i16, i1)
139 declare i64 @llvm.cttz.i64(i64, i1)
140 declare i32 @llvm.cttz.i32(i32, i1)
141 declare i16 @llvm.cttz.i16(i16, i1)