Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / EarlyCSE / ebstrict-strictfp.ll
blobfafc7ccbb38c1f756831b3c2caede4381175fae0
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
5 ; Test use of constrained floating point intrinsics with consistent
6 ; floating point environments. All tests are with strict exception
7 ; behavior and thus _no_ test should trigger CSE.
9 define double @fadd_strict(double %a, double %b) #0 {
10 ; CHECK-LABEL: @fadd_strict(
11 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]]
12 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
13 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
14 ; CHECK-NEXT:    ret double [[TMP2]]
16   %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
17   %2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
18   %3 = call double @foo.f64(double %1, double %2) #0
19   ret double %2
22 define double @fsub_strict(double %a, double %b) #0 {
23 ; CHECK-LABEL: @fsub_strict(
24 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
25 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
26 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
27 ; CHECK-NEXT:    ret double [[TMP2]]
29   %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
30   %2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
31   %3 = call double @foo.f64(double %1, double %2) #0
32   ret double %2
35 define double @fmul_strict(double %a, double %b) #0 {
36 ; CHECK-LABEL: @fmul_strict(
37 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
38 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
39 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
40 ; CHECK-NEXT:    ret double [[TMP2]]
42   %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
43   %2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
44   %3 = call double @foo.f64(double %1, double %2) #0
45   ret double %2
48 define double @fdiv_strict(double %a, double %b) #0 {
49 ; CHECK-LABEL: @fdiv_strict(
50 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
51 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
52 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
53 ; CHECK-NEXT:    ret double [[TMP2]]
55   %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
56   %2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
57   %3 = call double @foo.f64(double %1, double %2) #0
58   ret double %2
61 define double @frem_strict(double %a, double %b) #0 {
62 ; CHECK-LABEL: @frem_strict(
63 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
64 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
65 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
66 ; CHECK-NEXT:    ret double [[TMP2]]
68   %1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
69   %2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
70   %3 = call double @foo.f64(double %1, double %2) #0
71   ret double %2
74 define i32 @fptoui_strict(double %a) #0 {
75 ; CHECK-LABEL: @fptoui_strict(
76 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A:%.*]], metadata !"fpexcept.strict") #[[ATTR0]]
77 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double [[A]], metadata !"fpexcept.strict") #[[ATTR0]]
78 ; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
79 ; CHECK-NEXT:    ret i32 [[TMP2]]
81   %1 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.strict") #0
82   %2 = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %a, metadata !"fpexcept.strict") #0
83   %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
84   ret i32 %2
87 define double @uitofp_strict(i32 %a) #0 {
88 ; CHECK-LABEL: @uitofp_strict(
89 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
90 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
91 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
92 ; CHECK-NEXT:    ret double [[TMP2]]
94   %1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
95   %2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
96   %3 = call double @foo.f64(double %1, double %1) #0
97   ret double %2
100 define i32 @fptosi_strict(double %a) #0 {
101 ; CHECK-LABEL: @fptosi_strict(
102 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A:%.*]], metadata !"fpexcept.strict") #[[ATTR0]]
103 ; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double [[A]], metadata !"fpexcept.strict") #[[ATTR0]]
104 ; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @bar.i32(i32 [[TMP1]], i32 [[TMP1]]) #[[ATTR0]]
105 ; CHECK-NEXT:    ret i32 [[TMP2]]
107   %1 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.strict") #0
108   %2 = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %a, metadata !"fpexcept.strict") #0
109   %3 = call i32 @bar.i32(i32 %1, i32 %1) #0
110   ret i32 %2
113 define double @sitofp_strict(i32 %a) #0 {
114 ; CHECK-LABEL: @sitofp_strict(
115 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
116 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
117 ; CHECK-NEXT:    [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
118 ; CHECK-NEXT:    ret double [[TMP2]]
120   %1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
121   %2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
122   %3 = call double @foo.f64(double %1, double %1) #0
123   ret double %2
126 define i1 @fcmp_strict(double %a, double %b) #0 {
127 ; CHECK-LABEL: @fcmp_strict(
128 ; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
129 ; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
130 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
131 ; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
132 ; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
133 ; CHECK-NEXT:    ret i1 [[TMP2]]
135   %1 = call i1 @llvm.experimental.constrained.fcmp.i1.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
136   %2 = call i1 @llvm.experimental.constrained.fcmp.i1.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
137   %3 = zext i1 %1 to i32
138   %4 = zext i1 %2 to i32
139   %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
140   ret i1 %2
143 define i1 @fcmps_strict(double %a, double %b) #0 {
144 ; CHECK-LABEL: @fcmps_strict(
145 ; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A:%.*]], double [[B:%.*]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
146 ; CHECK-NEXT:    [[TMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double [[A]], double [[B]], metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]]
147 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP1]] to i32
148 ; CHECK-NEXT:    [[TMP4:%.*]] = zext i1 [[TMP2]] to i32
149 ; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @bar.i32(i32 [[TMP3]], i32 [[TMP4]]) #[[ATTR0]]
150 ; CHECK-NEXT:    ret i1 [[TMP2]]
152   %1 = call i1 @llvm.experimental.constrained.fcmps.i1.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
153   %2 = call i1 @llvm.experimental.constrained.fcmps.i1.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
154   %3 = zext i1 %1 to i32
155   %4 = zext i1 %2 to i32
156   %5 = call i32 @bar.i32(i32 %3, i32 %4) #0
157   ret i1 %2
160 attributes #0 = { strictfp }
162 declare void @arbitraryfunc() #0
163 declare double @foo.f64(double, double) #0
164 declare i32 @bar.i32(i32, i32) #0
166 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
167 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
168 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
169 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
170 declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
171 declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
172 declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
173 declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
174 declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
175 declare i1 @llvm.experimental.constrained.fcmp.i1.f64(double, double, metadata, metadata)
176 declare i1 @llvm.experimental.constrained.fcmps.i1.f64(double, double, metadata, metadata)