[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / fmul-pow.ll
blob70741554ac134caa7f3bb43d2f23d3cff72246a2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 declare double @llvm.pow.f64(double, double)
5 declare void @use(double)
7 define double @pow_ab_a(double %a, double %b)  {
8 ; CHECK-LABEL: @pow_ab_a(
9 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
10 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[TMP1]], [[A]]
11 ; CHECK-NEXT:    ret double [[MUL]]
13   %1 = call double @llvm.pow.f64(double %a, double %b)
14   %mul = fmul double %1, %a
15   ret double %mul
18 define double @pow_ab_a_reassoc(double %a, double %b)  {
19 ; CHECK-LABEL: @pow_ab_a_reassoc(
20 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
21 ; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[A]]
22 ; CHECK-NEXT:    ret double [[MUL]]
24   %1 = call double @llvm.pow.f64(double %a, double %b)
25   %mul = fmul reassoc double %1, %a
26   ret double %mul
29 define double @pow_ab_a_reassoc_commute(double %a, double %b)  {
30 ; CHECK-LABEL: @pow_ab_a_reassoc_commute(
31 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
32 ; CHECK-NEXT:    [[MUL:%.*]] = fdiv reassoc double [[TMP1]], [[A]]
33 ; CHECK-NEXT:    ret double [[MUL]]
35   %1 = fdiv double 1.0, %a
36   %2 = call double @llvm.pow.f64(double %a, double %b)
37   %mul = fmul reassoc double %1, %2
38   ret double %mul
41 define double @pow_ab_pow_cb(double %a, double %b, double %c) {
42 ; CHECK-LABEL: @pow_ab_pow_cb(
43 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
44 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.pow.f64(double [[C:%.*]], double [[B]])
45 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[TMP2]], [[TMP1]]
46 ; CHECK-NEXT:    ret double [[MUL]]
48   %1 = call double @llvm.pow.f64(double %a, double %b)
49   %2 = call double @llvm.pow.f64(double %c, double %b)
50   %mul = fmul double %2, %1
51   ret double %mul
54 define double @pow_ab_pow_cb_reassoc(double %a, double %b, double %c) {
55 ; CHECK-LABEL: @pow_ab_pow_cb_reassoc(
56 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
57 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.pow.f64(double [[C:%.*]], double [[B]])
58 ; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[TMP2]], [[TMP1]]
59 ; CHECK-NEXT:    ret double [[MUL]]
61   %1 = call double @llvm.pow.f64(double %a, double %b)
62   %2 = call double @llvm.pow.f64(double %c, double %b)
63   %mul = fmul reassoc double %2, %1
64   ret double %mul
67 define double @pow_ab_pow_ac(double %a, double %b, double %c) {
68 ; CHECK-LABEL: @pow_ab_pow_ac(
69 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
70 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A]], double [[C:%.*]])
71 ; CHECK-NEXT:    [[MUL:%.*]] = fmul double [[TMP2]], [[TMP1]]
72 ; CHECK-NEXT:    ret double [[MUL]]
74   %1 = call double @llvm.pow.f64(double %a, double %b)
75   %2 = call double @llvm.pow.f64(double %a, double %c)
76   %mul = fmul double %2, %1
77   ret double %mul
80 define double @pow_ab_x_pow_ac_reassoc(double %a, double %b, double %c) {
81 ; CHECK-LABEL: @pow_ab_x_pow_ac_reassoc(
82 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc double [[C:%.*]], [[B:%.*]]
83 ; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @llvm.pow.f64(double [[A:%.*]], double [[TMP1]])
84 ; CHECK-NEXT:    ret double [[TMP2]]
86   %1 = call double @llvm.pow.f64(double %a, double %b)
87   %2 = call double @llvm.pow.f64(double %a, double %c)
88   %mul = fmul reassoc double %2, %1
89   ret double %mul
92 define double @pow_ab_reassoc(double %a, double %b) {
93 ; CHECK-LABEL: @pow_ab_reassoc(
94 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc double [[B:%.*]], [[B]]
95 ; CHECK-NEXT:    [[TMP2:%.*]] = call reassoc double @llvm.pow.f64(double [[A:%.*]], double [[TMP1]])
96 ; CHECK-NEXT:    ret double [[TMP2]]
98   %1 = call double @llvm.pow.f64(double %a, double %b)
99   %mul = fmul reassoc double %1, %1
100   ret double %mul
103 define double @pow_ab_reassoc_extra_use(double %a, double %b) {
104 ; CHECK-LABEL: @pow_ab_reassoc_extra_use(
105 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
106 ; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[TMP1]]
107 ; CHECK-NEXT:    call void @use(double [[TMP1]])
108 ; CHECK-NEXT:    ret double [[MUL]]
110   %1 = call double @llvm.pow.f64(double %a, double %b)
111   %mul = fmul reassoc double %1, %1
112   call void @use(double %1)
113   ret double %mul
116 define double @pow_ab_x_pow_ac_reassoc_extra_use(double %a, double %b, double %c) {
117 ; CHECK-LABEL: @pow_ab_x_pow_ac_reassoc_extra_use(
118 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
119 ; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc double [[B]], [[C:%.*]]
120 ; CHECK-NEXT:    [[TMP3:%.*]] = call reassoc double @llvm.pow.f64(double [[A]], double [[TMP2]])
121 ; CHECK-NEXT:    call void @use(double [[TMP1]])
122 ; CHECK-NEXT:    ret double [[TMP3]]
124   %1 = call double @llvm.pow.f64(double %a, double %b)
125   %2 = call double @llvm.pow.f64(double %a, double %c)
126   %mul = fmul reassoc double %1, %2
127   call void @use(double %1)
128   ret double %mul
131 define double @pow_ab_x_pow_ac_reassoc_multiple_uses(double %a, double %b, double %c) {
132 ; CHECK-LABEL: @pow_ab_x_pow_ac_reassoc_multiple_uses(
133 ; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.pow.f64(double [[A:%.*]], double [[B:%.*]])
134 ; CHECK-NEXT:    [[TMP2:%.*]] = call double @llvm.pow.f64(double [[A]], double [[C:%.*]])
135 ; CHECK-NEXT:    [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[TMP2]]
136 ; CHECK-NEXT:    call void @use(double [[TMP1]])
137 ; CHECK-NEXT:    call void @use(double [[TMP2]])
138 ; CHECK-NEXT:    ret double [[MUL]]
140   %1 = call double @llvm.pow.f64(double %a, double %b)
141   %2 = call double @llvm.pow.f64(double %a, double %c)
142   %mul = fmul reassoc double %1, %2
143   call void @use(double %1)
144   call void @use(double %2)
145   ret double %mul