|
2 | 2 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
3 | 3 |
|
4 | 4 | declare void @use(i1)
|
| 5 | +declare void @usef64(double) |
5 | 6 |
|
6 | 7 | ; X == 42.0 ? X : 42.0 --> 42.0
|
7 | 8 |
|
@@ -148,3 +149,122 @@ define i1 @fcmp_ogt_select(i1 %cond, float %a, float %b) {
|
148 | 149 | %res = fcmp ogt float %lhs, %rhs
|
149 | 150 | ret i1 %res
|
150 | 151 | }
|
| 152 | + |
| 153 | +define i1 @test_fcmp_select_const_const(double %x) { |
| 154 | +; CHECK-LABEL: @test_fcmp_select_const_const( |
| 155 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00 |
| 156 | +; CHECK-NEXT: ret i1 [[CMP1]] |
| 157 | +; |
| 158 | + %cmp1 = fcmp ord double %x, 0.000000e+00 |
| 159 | + %sel = select i1 %cmp1, double 0xFFFFFFFFFFFFFFFF, double 0.000000e+00 |
| 160 | + %cmp2 = fcmp oeq double %sel, 0.000000e+00 |
| 161 | + ret i1 %cmp2 |
| 162 | +} |
| 163 | + |
| 164 | +define i1 @test_fcmp_select_var_const(double %x, double %y) { |
| 165 | +; CHECK-LABEL: @test_fcmp_select_var_const( |
| 166 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ule double [[X:%.*]], 0x3E80000000000000 |
| 167 | +; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt double [[Y:%.*]], 0x3E80000000000000 |
| 168 | +; CHECK-NEXT: [[CMP2:%.*]] = select i1 [[CMP1]], i1 true, i1 [[TMP1]] |
| 169 | +; CHECK-NEXT: ret i1 [[CMP2]] |
| 170 | +; |
| 171 | + %cmp1 = fcmp ogt double %x, 0x3E80000000000000 |
| 172 | + %sel = select i1 %cmp1, double %y, double 0.000000e+00 |
| 173 | + %cmp2 = fcmp olt double %sel, 0x3E80000000000000 |
| 174 | + ret i1 %cmp2 |
| 175 | +} |
| 176 | + |
| 177 | +define i1 @test_fcmp_select_var_const_fmf(double %x, double %y) { |
| 178 | +; CHECK-LABEL: @test_fcmp_select_var_const_fmf( |
| 179 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ule double [[X:%.*]], 0x3E80000000000000 |
| 180 | +; CHECK-NEXT: [[TMP1:%.*]] = fcmp nnan olt double [[Y:%.*]], 0x3E80000000000000 |
| 181 | +; CHECK-NEXT: [[CMP2:%.*]] = select i1 [[CMP1]], i1 true, i1 [[TMP1]] |
| 182 | +; CHECK-NEXT: ret i1 [[CMP2]] |
| 183 | +; |
| 184 | + %cmp1 = fcmp ogt double %x, 0x3E80000000000000 |
| 185 | + %sel = select i1 %cmp1, double %y, double 0.000000e+00 |
| 186 | + %cmp2 = fcmp nnan olt double %sel, 0x3E80000000000000 |
| 187 | + ret i1 %cmp2 |
| 188 | +} |
| 189 | + |
| 190 | +define <2 x i1> @test_fcmp_select_const_const_vec(<2 x double> %x) { |
| 191 | +; CHECK-LABEL: @test_fcmp_select_const_const_vec( |
| 192 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp uno <2 x double> [[X:%.*]], zeroinitializer |
| 193 | +; CHECK-NEXT: ret <2 x i1> [[CMP1]] |
| 194 | +; |
| 195 | + %cmp1 = fcmp ord <2 x double> %x, zeroinitializer |
| 196 | + %sel = select <2 x i1> %cmp1, <2 x double> <double 0xFFFFFFFFFFFFFFFF, double 0xFFFFFFFFFFFFFFFF>, <2 x double> zeroinitializer |
| 197 | + %cmp2 = fcmp oeq <2 x double> %sel, zeroinitializer |
| 198 | + ret <2 x i1> %cmp2 |
| 199 | +} |
| 200 | + |
| 201 | +; Don't break clamp idioms |
| 202 | + |
| 203 | +define double @test_fcmp_select_clamp(double %x) { |
| 204 | +; CHECK-LABEL: @test_fcmp_select_clamp( |
| 205 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt double [[X:%.*]], 9.000000e-01 |
| 206 | +; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], double 9.000000e-01, double [[X]] |
| 207 | +; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[SEL1]], 5.000000e-01 |
| 208 | +; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], double 5.000000e-01, double [[SEL1]] |
| 209 | +; CHECK-NEXT: ret double [[SEL2]] |
| 210 | +; |
| 211 | + %cmp1 = fcmp ogt double %x, 9.000000e-01 |
| 212 | + %sel1 = select i1 %cmp1, double 9.000000e-01, double %x |
| 213 | + %cmp2 = fcmp olt double %sel1, 5.000000e-01 |
| 214 | + %sel2 = select i1 %cmp2, double 5.000000e-01, double %sel1 |
| 215 | + ret double %sel2 |
| 216 | +} |
| 217 | + |
| 218 | +; Don't break fmin/fmax idioms |
| 219 | + |
| 220 | +define double @test_fcmp_select_maxnum(double %x) { |
| 221 | +; CHECK-LABEL: @test_fcmp_select_maxnum( |
| 222 | +; CHECK-NEXT: [[SEL1:%.*]] = call nnan nsz double @llvm.maxnum.f64(double [[X:%.*]], double 1.000000e+00) |
| 223 | +; CHECK-NEXT: [[SEL2:%.*]] = call nnan nsz double @llvm.minnum.f64(double [[SEL1]], double 2.550000e+02) |
| 224 | +; CHECK-NEXT: ret double [[SEL2]] |
| 225 | +; |
| 226 | + %cmp1 = fcmp ogt double %x, 1.0 |
| 227 | + %sel1 = select nnan nsz i1 %cmp1, double %x, double 1.0 |
| 228 | + %cmp2 = fcmp olt double %sel1, 255.0 |
| 229 | + %sel2 = select nnan nsz i1 %cmp2, double %sel1, double 255.0 |
| 230 | + ret double %sel2 |
| 231 | +} |
| 232 | + |
| 233 | +define i1 @test_fcmp_select_const_const_multiuse(double %x) { |
| 234 | +; CHECK-LABEL: @test_fcmp_select_const_const_multiuse( |
| 235 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord double [[X:%.*]], 0.000000e+00 |
| 236 | +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double 0xFFFFFFFFFFFFFFFF, double 0.000000e+00 |
| 237 | +; CHECK-NEXT: call void @usef64(double [[SEL]]) |
| 238 | +; CHECK-NEXT: [[CMP2:%.*]] = fcmp oeq double [[SEL]], 0.000000e+00 |
| 239 | +; CHECK-NEXT: ret i1 [[CMP2]] |
| 240 | +; |
| 241 | + %cmp1 = fcmp ord double %x, 0.000000e+00 |
| 242 | + %sel = select i1 %cmp1, double 0xFFFFFFFFFFFFFFFF, double 0.000000e+00 |
| 243 | + call void @usef64(double %sel) |
| 244 | + %cmp2 = fcmp oeq double %sel, 0.000000e+00 |
| 245 | + ret i1 %cmp2 |
| 246 | +} |
| 247 | + |
| 248 | +define i1 @test_fcmp_select_const_const_unordered(double %x) { |
| 249 | +; CHECK-LABEL: @test_fcmp_select_const_const_unordered( |
| 250 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ord double [[X:%.*]], 0.000000e+00 |
| 251 | +; CHECK-NEXT: ret i1 [[CMP1]] |
| 252 | +; |
| 253 | + %cmp1 = fcmp uno double %x, 0.000000e+00 |
| 254 | + %sel = select i1 %cmp1, double 0xFFFFFFFFFFFFFFFF, double 0.000000e+00 |
| 255 | + %cmp2 = fcmp oeq double %sel, 0.000000e+00 |
| 256 | + ret i1 %cmp2 |
| 257 | +} |
| 258 | + |
| 259 | +define i1 @test_fcmp_select_var_const_unordered(double %x, double %y) { |
| 260 | +; CHECK-LABEL: @test_fcmp_select_var_const_unordered( |
| 261 | +; CHECK-NEXT: [[CMP1:%.*]] = fcmp ult double [[X:%.*]], 0x3E80000000000000 |
| 262 | +; CHECK-NEXT: [[TMP1:%.*]] = fcmp ugt double [[Y:%.*]], 0x3E80000000000000 |
| 263 | +; CHECK-NEXT: [[CMP2:%.*]] = select i1 [[CMP1]], i1 [[TMP1]], i1 false |
| 264 | +; CHECK-NEXT: ret i1 [[CMP2]] |
| 265 | +; |
| 266 | + %cmp1 = fcmp ult double %x, 0x3E80000000000000 |
| 267 | + %sel = select i1 %cmp1, double %y, double 0.000000e+00 |
| 268 | + %cmp2 = fcmp ugt double %sel, 0x3E80000000000000 |
| 269 | + ret i1 %cmp2 |
| 270 | +} |
0 commit comments