xref: /llvm-project/clang/test/CodeGen/fpconstrained-cmp-float.c (revision 2b35511350454dd22997f129ee529e3fdb129ac2)
1 // RUN: %clang_cc1 -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=FCMP
2 // RUN: %clang_cc1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT
3 // RUN: %clang_cc1 -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP
4 // RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=IGNORE
5 // RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=EXCEPT
6 // RUN: %clang_cc1 -frounding-math -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=MAYTRAP
7 
8 // Disabled until constrained floating point is completed for PowerPC.
9 // XFAIL: powerpc, powerpc64, powerpc64le
10 
11 _Bool QuietEqual(float f1, float f2) {
12   // CHECK-LABEL: define {{.*}}i1 @QuietEqual(float %f1, float %f2)
13 
14   // FCMP: fcmp oeq float %{{.*}}, %{{.*}}
15   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oeq", metadata !"fpexcept.ignore")
16   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oeq", metadata !"fpexcept.strict")
17   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oeq", metadata !"fpexcept.maytrap")
18   return f1 == f2;
19 
20   // CHECK: ret
21 }
22 
23 _Bool QuietNotEqual(float f1, float f2) {
24   // CHECK-LABEL: define {{.*}}i1 @QuietNotEqual(float %f1, float %f2)
25 
26   // FCMP: fcmp une float %{{.*}}, %{{.*}}
27   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"une", metadata !"fpexcept.ignore")
28   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"une", metadata !"fpexcept.strict")
29   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"une", metadata !"fpexcept.maytrap")
30   return f1 != f2;
31 
32   // CHECK: ret
33 }
34 
35 _Bool SignalingLess(float f1, float f2) {
36   // CHECK-LABEL: define {{.*}}i1 @SignalingLess(float %f1, float %f2)
37 
38   // FCMP: fcmp olt float %{{.*}}, %{{.*}}
39   // IGNORE: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.ignore")
40   // EXCEPT: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.strict")
41   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.maytrap")
42   return f1 < f2;
43 
44   // CHECK: ret
45 }
46 
47 _Bool SignalingLessEqual(float f1, float f2) {
48   // CHECK-LABEL: define {{.*}}i1 @SignalingLessEqual(float %f1, float %f2)
49 
50   // FCMP: fcmp ole float %{{.*}}, %{{.*}}
51   // IGNORE: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.ignore")
52   // EXCEPT: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.strict")
53   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.maytrap")
54   return f1 <= f2;
55 
56   // CHECK: ret
57 }
58 
59 _Bool SignalingGreater(float f1, float f2) {
60   // CHECK-LABEL: define {{.*}}i1 @SignalingGreater(float %f1, float %f2)
61 
62   // FCMP: fcmp ogt float %{{.*}}, %{{.*}}
63   // IGNORE: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.ignore")
64   // EXCEPT: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.strict")
65   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.maytrap")
66   return f1 > f2;
67 
68   // CHECK: ret
69 }
70 
71 _Bool SignalingGreaterEqual(float f1, float f2) {
72   // CHECK-LABEL: define {{.*}}i1 @SignalingGreaterEqual(float %f1, float %f2)
73 
74   // FCMP: fcmp oge float %{{.*}}, %{{.*}}
75   // IGNORE: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.ignore")
76   // EXCEPT: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.strict")
77   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmps.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.maytrap")
78   return f1 >= f2;
79 
80   // CHECK: ret
81 }
82 
83 _Bool QuietLess(float f1, float f2) {
84   // CHECK-LABEL: define {{.*}}i1 @QuietLess(float %f1, float %f2)
85 
86   // FCMP: fcmp olt float %{{.*}}, %{{.*}}
87   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.ignore")
88   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.strict")
89   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"olt", metadata !"fpexcept.maytrap")
90   return __builtin_isless(f1, f2);
91 
92   // CHECK: ret
93 }
94 
95 _Bool QuietLessEqual(float f1, float f2) {
96   // CHECK-LABEL: define {{.*}}i1 @QuietLessEqual(float %f1, float %f2)
97 
98   // FCMP: fcmp ole float %{{.*}}, %{{.*}}
99   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.ignore")
100   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.strict")
101   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ole", metadata !"fpexcept.maytrap")
102   return __builtin_islessequal(f1, f2);
103 
104   // CHECK: ret
105 }
106 
107 _Bool QuietGreater(float f1, float f2) {
108   // CHECK-LABEL: define {{.*}}i1 @QuietGreater(float %f1, float %f2)
109 
110   // FCMP: fcmp ogt float %{{.*}}, %{{.*}}
111   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.ignore")
112   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.strict")
113   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"ogt", metadata !"fpexcept.maytrap")
114   return __builtin_isgreater(f1, f2);
115 
116   // CHECK: ret
117 }
118 
119 _Bool QuietGreaterEqual(float f1, float f2) {
120   // CHECK-LABEL: define {{.*}}i1 @QuietGreaterEqual(float %f1, float %f2)
121 
122   // FCMP: fcmp oge float %{{.*}}, %{{.*}}
123   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.ignore")
124   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.strict")
125   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"oge", metadata !"fpexcept.maytrap")
126   return __builtin_isgreaterequal(f1, f2);
127 
128   // CHECK: ret
129 }
130 
131 _Bool QuietLessGreater(float f1, float f2) {
132   // CHECK-LABEL: define {{.*}}i1 @QuietLessGreater(float %f1, float %f2)
133 
134   // FCMP: fcmp one float %{{.*}}, %{{.*}}
135   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"one", metadata !"fpexcept.ignore")
136   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"one", metadata !"fpexcept.strict")
137   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"one", metadata !"fpexcept.maytrap")
138   return __builtin_islessgreater(f1, f2);
139 
140   // CHECK: ret
141 }
142 
143 _Bool QuietUnordered(float f1, float f2) {
144   // CHECK-LABEL: define {{.*}}i1 @QuietUnordered(float %f1, float %f2)
145 
146   // FCMP: fcmp uno float %{{.*}}, %{{.*}}
147   // IGNORE: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"uno", metadata !"fpexcept.ignore")
148   // EXCEPT: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"uno", metadata !"fpexcept.strict")
149   // MAYTRAP: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, float %{{.*}}, metadata !"uno", metadata !"fpexcept.maytrap")
150   return __builtin_isunordered(f1, f2);
151 
152   // CHECK: ret
153 }
154 
155