xref: /llvm-project/llvm/test/Transforms/EarlyCSE/tfpropagation.ll (revision ac696ac4530fb3df626195e94e83649bf7114754)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -passes=early-cse -earlycse-debug-hash | FileCheck %s
3; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s
4
5define i64 @branching_int(i32 %a) {
6; CHECK-LABEL: @branching_int(
7; CHECK-NEXT:    [[CONV1:%.*]] = zext i32 [[A:%.*]] to i64
8; CHECK-NEXT:    [[CMP2:%.*]] = icmp ugt i64 1, [[CONV1]]
9; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
10; CHECK:       if.then3:
11; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 true)
12; CHECK-NEXT:    br label [[OUT:%.*]]
13; CHECK:       if.end3:
14; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 false)
15; CHECK-NEXT:    br label [[OUT]]
16; CHECK:       out:
17; CHECK-NEXT:    ret i64 [[CONV1]]
18;
19  %conv1 = zext i32 %a to i64
20  %cmp2 = icmp ugt i64 1, %conv1
21  br i1 %cmp2, label %if.then3, label %if.end3
22
23if.then3:
24  %c = call double @truefunc.f64.i1(i1 %cmp2)
25  br label %out
26
27if.end3:
28  %d = call double @falsefunc.f64.i1(i1 %cmp2)
29  br label %out
30
31out:
32  ret i64 %conv1
33}
34
35define double @branching_fp(i64 %a) {
36; CHECK-LABEL: @branching_fp(
37; CHECK-NEXT:    [[CONV1:%.*]] = uitofp i64 [[A:%.*]] to double
38; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ogt double 1.000000e+00, [[CONV1]]
39; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
40; CHECK:       if.then3:
41; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 true)
42; CHECK-NEXT:    br label [[OUT:%.*]]
43; CHECK:       if.end3:
44; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 false)
45; CHECK-NEXT:    br label [[OUT]]
46; CHECK:       out:
47; CHECK-NEXT:    ret double [[CONV1]]
48;
49  %conv1 = uitofp i64 %a to double
50  %cmp2 = fcmp ogt double 1.000000e+00, %conv1
51  br i1 %cmp2, label %if.then3, label %if.end3
52
53if.then3:
54  %c = call double @truefunc.f64.i1(i1 %cmp2)
55  br label %out
56
57if.end3:
58  %d = call double @falsefunc.f64.i1(i1 %cmp2)
59  br label %out
60
61out:
62  ret double %conv1
63}
64
65define double @branching_exceptignore(i64 %a) #0 {
66; CHECK-LABEL: @branching_exceptignore(
67; CHECK-NEXT:    [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
68; CHECK-NEXT:    [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]]
69; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
70; CHECK:       if.then3:
71; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]]
72; CHECK-NEXT:    br label [[OUT:%.*]]
73; CHECK:       if.end3:
74; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]]
75; CHECK-NEXT:    br label [[OUT]]
76; CHECK:       out:
77; CHECK-NEXT:    ret double [[CONV1]]
78;
79  %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
80  %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0
81  br i1 %cmp2, label %if.then3, label %if.end3
82
83if.then3:
84  %c = call double @truefunc.f64.i1(i1 %cmp2) #0
85  br label %out
86
87if.end3:
88  %d = call double @falsefunc.f64.i1(i1 %cmp2) #0
89  br label %out
90
91out:
92  ret double %conv1
93}
94
95define double @branching_exceptignore_dynround(i64 %a) #0 {
96; CHECK-LABEL: @branching_exceptignore_dynround(
97; CHECK-NEXT:    [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
98; CHECK-NEXT:    [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]]
99; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
100; CHECK:       if.then3:
101; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]]
102; CHECK-NEXT:    br label [[OUT:%.*]]
103; CHECK:       if.end3:
104; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]]
105; CHECK-NEXT:    br label [[OUT]]
106; CHECK:       out:
107; CHECK-NEXT:    ret double [[CONV1]]
108;
109  %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
110  %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0
111  br i1 %cmp2, label %if.then3, label %if.end3
112
113if.then3:
114  %c = call double @truefunc.f64.i1(i1 %cmp2) #0
115  br label %out
116
117if.end3:
118  %d = call double @falsefunc.f64.i1(i1 %cmp2) #0
119  br label %out
120
121out:
122  ret double %conv1
123}
124
125define double @branching_maytrap(i64 %a) #0 {
126; CHECK-LABEL: @branching_maytrap(
127; CHECK-NEXT:    [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
128; CHECK-NEXT:    [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.maytrap") #[[ATTR0]]
129; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
130; CHECK:       if.then3:
131; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]]
132; CHECK-NEXT:    br label [[OUT:%.*]]
133; CHECK:       if.end3:
134; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]]
135; CHECK-NEXT:    br label [[OUT]]
136; CHECK:       out:
137; CHECK-NEXT:    ret double [[CONV1]]
138;
139  %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
140  %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.maytrap") #0
141  br i1 %cmp2, label %if.then3, label %if.end3
142
143if.then3:
144  %c = call double @truefunc.f64.i1(i1 %cmp2) #0
145  br label %out
146
147if.end3:
148  %d = call double @falsefunc.f64.i1(i1 %cmp2) #0
149  br label %out
150
151out:
152  ret double %conv1
153}
154
155; TODO: Fix this optimization so it works with strict exception behavior.
156; TODO: This may or may not be worth the added complication and risk.
157define double @branching_ebstrict(i64 %a) #0 {
158; CHECK-LABEL: @branching_ebstrict(
159; CHECK-NEXT:    [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
160; CHECK-NEXT:    [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.strict") #[[ATTR0]]
161; CHECK-NEXT:    br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
162; CHECK:       if.then3:
163; CHECK-NEXT:    [[C:%.*]] = call double @truefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]]
164; CHECK-NEXT:    br label [[OUT:%.*]]
165; CHECK:       if.end3:
166; CHECK-NEXT:    [[D:%.*]] = call double @falsefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]]
167; CHECK-NEXT:    br label [[OUT]]
168; CHECK:       out:
169; CHECK-NEXT:    ret double [[CONV1]]
170;
171  %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
172  %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.strict") #0
173  br i1 %cmp2, label %if.then3, label %if.end3
174
175if.then3:
176  %c = call double @truefunc.f64.i1(i1 %cmp2) #0
177  br label %out
178
179if.end3:
180  %d = call double @falsefunc.f64.i1(i1 %cmp2) #0
181  br label %out
182
183out:
184  ret double %conv1
185}
186
187declare double @truefunc.f64.i1(i1)
188declare double @falsefunc.f64.i1(i1)
189declare double @llvm.experimental.constrained.uitofp.f64.i64(i64, metadata, metadata) #0
190declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata) #0
191
192attributes #0 = { strictfp }
193
194declare <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float>, <4 x float>, metadata, metadata) strictfp
195