@@ -401,6 +401,121 @@ define double @fdiv_pow_powi_negative_variable(double %x, i32 %y) {
401
401
ret double %div
402
402
}
403
403
404
+ ; powi(X,C1)/ (X * Z) --> powi(X,C1 - 1)/ Z
405
+ define double @fdiv_fmul_powi (double %a , double %z ) {
406
+ ; CHECK-LABEL: @fdiv_fmul_powi(
407
+ ; CHECK-NEXT: [[TMP1:%.*]] = call reassoc nnan double @llvm.powi.f64.i32(double [[A:%.*]], i32 4)
408
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[TMP1]], [[Z:%.*]]
409
+ ; CHECK-NEXT: ret double [[DIV]]
410
+ ;
411
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
412
+ %square = fmul reassoc double %z , %a
413
+ %div = fdiv reassoc nnan double %pow , %square
414
+ ret double %div
415
+ }
416
+
417
+ ; powi(X, 5)/ (X * X) --> powi(X, 4)/ X -> powi(X, 3)
418
+ define double @fdiv_fmul_powi_2 (double %a ) {
419
+ ; CHECK-LABEL: @fdiv_fmul_powi_2(
420
+ ; CHECK-NEXT: [[DIV:%.*]] = call reassoc nnan double @llvm.powi.f64.i32(double [[A:%.*]], i32 3)
421
+ ; CHECK-NEXT: ret double [[DIV]]
422
+ ;
423
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
424
+ %square = fmul reassoc double %a , %a
425
+ %div = fdiv reassoc nnan double %pow , %square
426
+ ret double %div
427
+ }
428
+
429
+ define <2 x float > @fdiv_fmul_powi_vector (<2 x float > %a ) {
430
+ ; CHECK-LABEL: @fdiv_fmul_powi_vector(
431
+ ; CHECK-NEXT: [[DIV:%.*]] = call reassoc nnan <2 x float> @llvm.powi.v2f32.i32(<2 x float> [[A:%.*]], i32 3)
432
+ ; CHECK-NEXT: ret <2 x float> [[DIV]]
433
+ ;
434
+ %pow = call reassoc <2 x float > @llvm.powi.v2f32.i32 (<2 x float > %a , i32 5 )
435
+ %square = fmul reassoc <2 x float > %a , %a
436
+ %div = fdiv reassoc nnan <2 x float > %pow , %square
437
+ ret <2 x float > %div
438
+ }
439
+
440
+ ; Negative test
441
+ define double @fdiv_fmul_powi_missing_reassoc1 (double %a ) {
442
+ ; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc1(
443
+ ; CHECK-NEXT: [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)
444
+ ; CHECK-NEXT: [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]
445
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan double [[POW]], [[SQUARE]]
446
+ ; CHECK-NEXT: ret double [[DIV]]
447
+ ;
448
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
449
+ %square = fmul reassoc double %a , %a
450
+ %div = fdiv nnan double %pow , %square
451
+ ret double %div
452
+ }
453
+
454
+ define double @fdiv_fmul_powi_missing_reassoc2 (double %a ) {
455
+ ; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc2(
456
+ ; CHECK-NEXT: [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)
457
+ ; CHECK-NEXT: [[SQUARE:%.*]] = fmul double [[A]], [[A]]
458
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]
459
+ ; CHECK-NEXT: ret double [[DIV]]
460
+ ;
461
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
462
+ %square = fmul double %a , %a
463
+ %div = fdiv reassoc nnan double %pow , %square
464
+ ret double %div
465
+ }
466
+
467
+ define double @fdiv_fmul_powi_missing_reassoc3 (double %a ) {
468
+ ; CHECK-LABEL: @fdiv_fmul_powi_missing_reassoc3(
469
+ ; CHECK-NEXT: [[POW:%.*]] = call double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)
470
+ ; CHECK-NEXT: [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]
471
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]
472
+ ; CHECK-NEXT: ret double [[DIV]]
473
+ ;
474
+ %pow = call double @llvm.powi.f64.i32 (double %a , i32 5 )
475
+ %square = fmul reassoc double %a , %a
476
+ %div = fdiv reassoc nnan double %pow , %square
477
+ ret double %div
478
+ }
479
+
480
+ define double @fdiv_fmul_powi_missing_nnan (double %a ) {
481
+ ; CHECK-LABEL: @fdiv_fmul_powi_missing_nnan(
482
+ ; CHECK-NEXT: [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)
483
+ ; CHECK-NEXT: [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]
484
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc double [[POW]], [[SQUARE]]
485
+ ; CHECK-NEXT: ret double [[DIV]]
486
+ ;
487
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
488
+ %square = fmul reassoc double %a , %a
489
+ %div = fdiv reassoc double %pow , %square
490
+ ret double %div
491
+ }
492
+
493
+ define double @fdiv_fmul_powi_negative_wrap (double noundef %x ) {
494
+ ; CHECK-LABEL: @fdiv_fmul_powi_negative_wrap(
495
+ ; CHECK-NEXT: [[P1:%.*]] = tail call double @llvm.powi.f64.i32(double [[X:%.*]], i32 -2147483648)
496
+ ; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[P1]], [[X]]
497
+ ; CHECK-NEXT: ret double [[MUL]]
498
+ ;
499
+ %p1 = tail call double @llvm.powi.f64.i32 (double %x , i32 -2147483648 ) ; INT_MIN
500
+ %mul = fmul reassoc double %p1 , %x
501
+ ret double %mul
502
+ }
503
+
504
+ define double @fdiv_fmul_powi_multi_use (double %a ) {
505
+ ; CHECK-LABEL: @fdiv_fmul_powi_multi_use(
506
+ ; CHECK-NEXT: [[POW:%.*]] = call reassoc double @llvm.powi.f64.i32(double [[A:%.*]], i32 5)
507
+ ; CHECK-NEXT: tail call void @use(double [[POW]])
508
+ ; CHECK-NEXT: [[SQUARE:%.*]] = fmul reassoc double [[A]], [[A]]
509
+ ; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan double [[POW]], [[SQUARE]]
510
+ ; CHECK-NEXT: ret double [[DIV]]
511
+ ;
512
+ %pow = call reassoc double @llvm.powi.f64.i32 (double %a , i32 5 )
513
+ tail call void @use (double %pow )
514
+ %square = fmul reassoc double %a , %a
515
+ %div = fdiv reassoc nnan double %pow , %square
516
+ ret double %div
517
+ }
518
+
404
519
; powi(X, Y) * X --> powi(X, Y+1)
405
520
define double @powi_fmul_powi_x (double noundef %x ) {
406
521
; CHECK-LABEL: @powi_fmul_powi_x(
0 commit comments