|
2 | 2 | ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
|
3 | 3 |
|
4 | 4 | declare double @llvm.powi.f64.i32(double, i32)
|
| 5 | +declare float @llvm.powi.f32.i32(float, i32) |
5 | 6 | declare double @llvm.powi.f64.i64(double, i64)
|
6 | 7 | declare double @llvm.fabs.f64(double)
|
7 | 8 | declare double @llvm.copysign.f64(double, double)
|
@@ -258,3 +259,87 @@ define double @different_types_powi(double %x, i32 %y, i64 %z) {
|
258 | 259 | %mul = fmul reassoc double %p2, %p1
|
259 | 260 | ret double %mul
|
260 | 261 | }
|
| 262 | + |
| 263 | +define double @fdiv_pow_powi(double %x) { |
| 264 | +; CHECK-LABEL: @fdiv_pow_powi( |
| 265 | +; CHECK-NEXT: [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3) |
| 266 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]] |
| 267 | +; CHECK-NEXT: ret double [[DIV]] |
| 268 | +; |
| 269 | + %p1 = call double @llvm.powi.f64.i32(double %x, i32 3) |
| 270 | + %div = fdiv reassoc nnan double %p1, %x |
| 271 | + ret double %div |
| 272 | +} |
| 273 | + |
| 274 | +define float @fdiv_powf_powi(float %x) { |
| 275 | +; CHECK-LABEL: @fdiv_powf_powi( |
| 276 | +; CHECK-NEXT: [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100) |
| 277 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan float [[P1]], [[X]] |
| 278 | +; CHECK-NEXT: ret float [[DIV]] |
| 279 | +; |
| 280 | + %p1 = call float @llvm.powi.f32.i32(float %x, i32 100) |
| 281 | + %div = fdiv reassoc nnan float %p1, %x |
| 282 | + ret float %div |
| 283 | +} |
| 284 | + |
| 285 | +; TODO: Multi-use may be also better off creating Powi(x,y-1) then creating |
| 286 | +; (mul, Powi(x,y-1),x) to replace the Powi(x,y). |
| 287 | +define double @fdiv_pow_powi_multi_use(double %x) { |
| 288 | +; CHECK-LABEL: @fdiv_pow_powi_multi_use( |
| 289 | +; CHECK-NEXT: [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 3) |
| 290 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]] |
| 291 | +; CHECK-NEXT: tail call void @use(double [[P1]]) |
| 292 | +; CHECK-NEXT: ret double [[DIV]] |
| 293 | +; |
| 294 | + %p1 = call double @llvm.powi.f64.i32(double %x, i32 3) |
| 295 | + %div = fdiv reassoc nnan double %p1, %x |
| 296 | + tail call void @use(double %p1) |
| 297 | + ret double %div |
| 298 | +} |
| 299 | + |
| 300 | +; Negative test: Miss part of the fmf flag for the fdiv instruction |
| 301 | +define float @fdiv_powf_powi_missing_reassoc(float %x) { |
| 302 | +; CHECK-LABEL: @fdiv_powf_powi_missing_reassoc( |
| 303 | +; CHECK-NEXT: [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100) |
| 304 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float [[P1]], [[X]] |
| 305 | +; CHECK-NEXT: ret float [[DIV]] |
| 306 | +; |
| 307 | + %p1 = call float @llvm.powi.f32.i32(float %x, i32 100) |
| 308 | + %div = fdiv nnan float %p1, %x |
| 309 | + ret float %div |
| 310 | +} |
| 311 | + |
| 312 | +define float @fdiv_powf_powi_missing_nnan(float %x) { |
| 313 | +; CHECK-LABEL: @fdiv_powf_powi_missing_nnan( |
| 314 | +; CHECK-NEXT: [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100) |
| 315 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc float [[P1]], [[X]] |
| 316 | +; CHECK-NEXT: ret float [[DIV]] |
| 317 | +; |
| 318 | + %p1 = call float @llvm.powi.f32.i32(float %x, i32 100) |
| 319 | + %div = fdiv reassoc float %p1, %x |
| 320 | + ret float %div |
| 321 | +} |
| 322 | + |
| 323 | +; Negative test: Illegal because (Y - 1) wraparound |
| 324 | +define double @fdiv_pow_powi_negative(double %x) { |
| 325 | +; CHECK-LABEL: @fdiv_pow_powi_negative( |
| 326 | +; CHECK-NEXT: [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 -2147483648) |
| 327 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]] |
| 328 | +; CHECK-NEXT: ret double [[DIV]] |
| 329 | +; |
| 330 | + %p1 = call double @llvm.powi.f64.i32(double %x, i32 -2147483648) ; INT_MIN |
| 331 | + %div = fdiv reassoc nnan double %p1, %x |
| 332 | + ret double %div |
| 333 | +} |
| 334 | + |
| 335 | +; Negative test: The 2nd powi argument is a variable |
| 336 | +define double @fdiv_pow_powi_negative_variable(double %x, i32 %y) { |
| 337 | +; CHECK-LABEL: @fdiv_pow_powi_negative_variable( |
| 338 | +; CHECK-NEXT: [[P1:%.*]] = call double @llvm.powi.f64.i32(double [[X:%.*]], i32 [[Y:%.*]]) |
| 339 | +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[P1]], [[X]] |
| 340 | +; CHECK-NEXT: ret double [[DIV]] |
| 341 | +; |
| 342 | + %p1 = call double @llvm.powi.f64.i32(double %x, i32 %y) |
| 343 | + %div = fdiv reassoc nnan double %p1, %x |
| 344 | + ret double %div |
| 345 | +} |
0 commit comments