442e8677e97728a9ee4e5a64984da90b3f915c32
[oota-llvm.git] / test / Transforms / SimplifyCFG / speculate-math.ll
1 ; RUN: opt -S -simplifycfg -phi-node-folding-threshold=2 < %s | FileCheck %s
2
3 declare float @llvm.sqrt.f32(float) nounwind readonly
4 declare float @llvm.fma.f32(float, float, float) nounwind readonly
5 declare float @llvm.fmuladd.f32(float, float, float) nounwind readonly
6 declare float @llvm.fabs.f32(float) nounwind readonly
7 declare float @llvm.minnum.f32(float, float) nounwind readonly
8 declare float @llvm.maxnum.f32(float, float) nounwind readonly
9
10 ; FIXME: This is intended to be a temporary test. As discussed in 
11 ; D12882, we actually do want to speculate even expensive operations
12 ; in SimplifyCFG because it can expose more optimizations for other
13 ; passes. Therefore, we either need to adjust SimplifyCFG's 
14 ; calculations that use the TTI cost model or use a different cost
15 ; model for deciding which ops should be speculated in SimplifyCFG. 
16 ; We should also be using the TTI cost model later - for example in
17 ; CodeGenPrepare - to potentially undo this speculation.
18
19 ; Do not speculate fdiv by default because it is generally expensive. 
20
21 ; CHECK-LABEL: @fdiv_test(
22 ; CHECK-NOT: select
23 define double @fdiv_test(double %a, double %b) {
24 entry:
25   %cmp = fcmp ogt double %a, 0.0
26   br i1 %cmp, label %cond.true, label %cond.end
27
28 cond.true:
29   %div = fdiv double %b, %a
30   br label %cond.end
31
32 cond.end:
33   %cond = phi double [ %div, %cond.true ], [ 0.0, %entry ]
34   ret double %cond
35 }
36
37 ; CHECK-LABEL: @sqrt_test(
38 ; CHECK: select
39 define void @sqrt_test(float addrspace(1)* noalias nocapture %out, float %a) nounwind {
40 entry:
41   %cmp.i = fcmp olt float %a, 0.000000e+00
42   br i1 %cmp.i, label %test_sqrt.exit, label %cond.else.i
43
44 cond.else.i:                                      ; preds = %entry
45   %0 = tail call float @llvm.sqrt.f32(float %a) nounwind readnone
46   br label %test_sqrt.exit
47
48 test_sqrt.exit:                                   ; preds = %cond.else.i, %entry
49   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
50   store float %cond.i, float addrspace(1)* %out, align 4
51   ret void
52 }
53
54 ; CHECK-LABEL: @fabs_test(
55 ; CHECK: select
56 define void @fabs_test(float addrspace(1)* noalias nocapture %out, float %a) nounwind {
57 entry:
58   %cmp.i = fcmp olt float %a, 0.000000e+00
59   br i1 %cmp.i, label %test_fabs.exit, label %cond.else.i
60
61 cond.else.i:                                      ; preds = %entry
62   %0 = tail call float @llvm.fabs.f32(float %a) nounwind readnone
63   br label %test_fabs.exit
64
65 test_fabs.exit:                                   ; preds = %cond.else.i, %entry
66   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
67   store float %cond.i, float addrspace(1)* %out, align 4
68   ret void
69 }
70
71 ; CHECK-LABEL: @fma_test(
72 ; CHECK: select
73 define void @fma_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind {
74 entry:
75   %cmp.i = fcmp olt float %a, 0.000000e+00
76   br i1 %cmp.i, label %test_fma.exit, label %cond.else.i
77
78 cond.else.i:                                      ; preds = %entry
79   %0 = tail call float @llvm.fma.f32(float %a, float %b, float %c) nounwind readnone
80   br label %test_fma.exit
81
82 test_fma.exit:                                   ; preds = %cond.else.i, %entry
83   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
84   store float %cond.i, float addrspace(1)* %out, align 4
85   ret void
86 }
87
88 ; CHECK-LABEL: @fmuladd_test(
89 ; CHECK: select
90 define void @fmuladd_test(float addrspace(1)* noalias nocapture %out, float %a, float %b, float %c) nounwind {
91 entry:
92   %cmp.i = fcmp olt float %a, 0.000000e+00
93   br i1 %cmp.i, label %test_fmuladd.exit, label %cond.else.i
94
95 cond.else.i:                                      ; preds = %entry
96   %0 = tail call float @llvm.fmuladd.f32(float %a, float %b, float %c) nounwind readnone
97   br label %test_fmuladd.exit
98
99 test_fmuladd.exit:                                   ; preds = %cond.else.i, %entry
100   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
101   store float %cond.i, float addrspace(1)* %out, align 4
102   ret void
103 }
104
105 ; CHECK-LABEL: @minnum_test(
106 ; CHECK: select
107 define void @minnum_test(float addrspace(1)* noalias nocapture %out, float %a, float %b) nounwind {
108 entry:
109   %cmp.i = fcmp olt float %a, 0.000000e+00
110   br i1 %cmp.i, label %test_minnum.exit, label %cond.else.i
111
112 cond.else.i:                                      ; preds = %entry
113   %0 = tail call float @llvm.minnum.f32(float %a, float %b) nounwind readnone
114   br label %test_minnum.exit
115
116 test_minnum.exit:                                   ; preds = %cond.else.i, %entry
117   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
118   store float %cond.i, float addrspace(1)* %out, align 4
119   ret void
120 }
121
122 ; CHECK-LABEL: @maxnum_test(
123 ; CHECK: select
124 define void @maxnum_test(float addrspace(1)* noalias nocapture %out, float %a, float %b) nounwind {
125 entry:
126   %cmp.i = fcmp olt float %a, 0.000000e+00
127   br i1 %cmp.i, label %test_maxnum.exit, label %cond.else.i
128
129 cond.else.i:                                      ; preds = %entry
130   %0 = tail call float @llvm.maxnum.f32(float %a, float %b) nounwind readnone
131   br label %test_maxnum.exit
132
133 test_maxnum.exit:                                   ; preds = %cond.else.i, %entry
134   %cond.i = phi float [ %0, %cond.else.i ], [ 0x7FF8000000000000, %entry ]
135   store float %cond.i, float addrspace(1)* %out, align 4
136   ret void
137 }