aboutsummaryrefslogtreecommitdiff
path: root/test/Transforms/InstCombine
diff options
context:
space:
mode:
authorShuxin Yang <shuxin.llvm@gmail.com>2013-01-15 21:09:32 +0000
committerShuxin Yang <shuxin.llvm@gmail.com>2013-01-15 21:09:32 +0000
commita1444219b271cab6fbfe340c1328b0ab10d8f7b6 (patch)
treedeff228206d9bad8b9ed44f4e1467e3dcb99d00d /test/Transforms/InstCombine
parent3d69041abe8a9833e78f645f0d4d7b95b802e3c4 (diff)
1. Hoist minus sign as high as possible in an attempt to reveal
some optimization opportunities (in the enclosing supper-expressions). rule 1. (-0.0 - X ) * Y => -0.0 - (X * Y) if expression "-0.0 - X" has only one reference. rule 2. (0.0 - X ) * Y => -0.0 - (X * Y) if expression "0.0 - X" has only one reference, and the instruction is marked "noSignedZero". 2. Eliminate negation (The compiler was already able to handle these opt if the 0.0s are replaced with -0.0.) rule 3: (0.0 - X) * (0.0 - Y) => X * Y rule 4: (0.0 - X) * C => X * -C if the expr is flagged "noSignedZero". 3. Rule 5: (X*Y) * X => (X*X) * Y if X!=Y and the expression is flagged with "UnsafeAlgebra". The purpose of this transformation is two-fold: a) to form a power expression (of X). b) potentially shorten the critical path: After transformation, the latency of the instruction Y is amortized by the expression of X*X, and therefore Y is in a "less critical" position compared to what it was before the transformation. 4. Remove the InstCombine code about simplifiying "X * select". The reasons are following: a) The "select" is somewhat architecture-dependent, therefore the higher level optimizers are not able to precisely predict if the simplification really yields any performance improvement or not. b) The "select" operator is bit complicate, and tends to obscure optimization opportunities. It is btter to keep it as low as possible in expr tree, and let CodeGen to tackle the optimization. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172551 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/InstCombine')
-rw-r--r--test/Transforms/InstCombine/fast-math.ll53
-rw-r--r--test/Transforms/InstCombine/fmul.ll72
2 files changed, 92 insertions, 33 deletions
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index 5a1ad5e6db..88e19e343a 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -130,37 +130,6 @@ define double @fail2(double %f1, double %f2) {
; CHECK: ret
}
-; rdar://12753946: x * cond ? 1.0 : 0.0 => cond ? x : 0.0
-define double @select1(i32 %cond, double %x, double %y) {
- %tobool = icmp ne i32 %cond, 0
- %cond1 = select i1 %tobool, double 1.000000e+00, double 0.000000e+00
- %mul = fmul nnan nsz double %cond1, %x
- %add = fadd double %mul, %y
- ret double %add
-; CHECK: @select1
-; CHECK: select i1 %tobool, double %x, double 0.000000e+00
-}
-
-define double @select2(i32 %cond, double %x, double %y) {
- %tobool = icmp ne i32 %cond, 0
- %cond1 = select i1 %tobool, double 0.000000e+00, double 1.000000e+00
- %mul = fmul nnan nsz double %cond1, %x
- %add = fadd double %mul, %y
- ret double %add
-; CHECK: @select2
-; CHECK: select i1 %tobool, double 0.000000e+00, double %x
-}
-
-define double @select3(i32 %cond, double %x, double %y) {
- %tobool = icmp ne i32 %cond, 0
- %cond1 = select i1 %tobool, double 0.000000e+00, double 2.000000e+00
- %mul = fmul nnan nsz double %cond1, %x
- %add = fadd double %mul, %y
- ret double %add
-; CHECK: @select3
-; CHECK: fmul nnan nsz double %cond1, %x
-}
-
; =========================================================================
;
; Testing-cases about fmul begin
@@ -243,6 +212,25 @@ define float @fmul5(float %f1, float %f2) {
; CHECK: fdiv fast float %f1, 0x47E8000000000000
}
+; (X*Y) * X => (X*X) * Y
+define float @fmul6(float %f1, float %f2) {
+ %mul = fmul float %f1, %f2
+ %mul1 = fmul fast float %mul, %f1
+ ret float %mul1
+; CHECK: @fmul6
+; CHECK: fmul fast float %f1, %f1
+}
+
+; "(X*Y) * X => (X*X) * Y" is disabled if "X*Y" has multiple uses
+define float @fmul7(float %f1, float %f2) {
+ %mul = fmul float %f1, %f2
+ %mul1 = fmul fast float %mul, %f1
+ %add = fadd float %mul1, %mul
+ ret float %add
+; CHECK: @fmul7
+; CHECK: fmul fast float %mul, %f1
+}
+
; =========================================================================
;
; Testing-cases about negation
@@ -262,8 +250,8 @@ define float @fneg1(float %f1, float %f2) {
; Testing-cases about div
;
; =========================================================================
-; X/C1 / C2 => X * (1/(C2*C1))
+; X/C1 / C2 => X * (1/(C2*C1))
define float @fdiv1(float %x) {
%div = fdiv float %x, 0x3FF3333340000000
%div1 = fdiv fast float %div, 0x4002666660000000
@@ -351,4 +339,3 @@ define float @fdiv9(float %x) {
; CHECK: @fdiv9
; CHECK: fmul fast float %x, 5.000000e+00
}
-
diff --git a/test/Transforms/InstCombine/fmul.ll b/test/Transforms/InstCombine/fmul.ll
new file mode 100644
index 0000000000..3671b4c699
--- /dev/null
+++ b/test/Transforms/InstCombine/fmul.ll
@@ -0,0 +1,72 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+
+; (-0.0 - X) * C => X * -C
+define float @test1(float %x) {
+ %sub = fsub float -0.000000e+00, %x
+ %mul = fmul float %sub, 2.0e+1
+ ret float %mul
+
+; CHECK: @test1
+; CHECK: fmul float %x, -2.000000e+01
+}
+
+; (0.0 - X) * C => X * -C
+define float @test2(float %x) {
+ %sub = fsub nsz float 0.000000e+00, %x
+ %mul = fmul float %sub, 2.0e+1
+ ret float %mul
+
+; CHECK: @test2
+; CHECK: fmul float %x, -2.000000e+01
+}
+
+; (-0.0 - X) * (-0.0 - Y) => X * Y
+define float @test3(float %x, float %y) {
+ %sub1 = fsub float -0.000000e+00, %x
+ %sub2 = fsub float -0.000000e+00, %y
+ %mul = fmul float %sub1, %sub2
+ ret float %mul
+; CHECK: @test3
+; CHECK: fmul float %x, %y
+}
+
+; (0.0 - X) * (0.0 - Y) => X * Y
+define float @test4(float %x, float %y) {
+ %sub1 = fsub nsz float 0.000000e+00, %x
+ %sub2 = fsub nsz float 0.000000e+00, %y
+ %mul = fmul float %sub1, %sub2
+ ret float %mul
+; CHECK: @test4
+; CHECK: fmul float %x, %y
+}
+
+; (-0.0 - X) * Y => -0.0 - (X * Y)
+define float @test5(float %x, float %y) {
+ %sub1 = fsub float -0.000000e+00, %x
+ %mul = fmul float %sub1, %y
+ ret float %mul
+; CHECK: @test5
+; CHECK: %1 = fmul float %x, %y
+; CHECK: %mul = fsub float -0.000000e+00, %1
+}
+
+; (0.0 - X) * Y => 0.0 - (X * Y)
+define float @test6(float %x, float %y) {
+ %sub1 = fsub nsz float 0.000000e+00, %x
+ %mul = fmul float %sub1, %y
+ ret float %mul
+; CHECK: @test6
+; CHECK: %1 = fmul float %x, %y
+; CHECK: %mul = fsub float -0.000000e+00, %1
+}
+
+; "(-0.0 - X) * Y => -0.0 - (X * Y)" is disabled if expression "-0.0 - X"
+; has multiple uses.
+define float @test7(float %x, float %y) {
+ %sub1 = fsub float -0.000000e+00, %x
+ %mul = fmul float %sub1, %y
+ %mul2 = fmul float %mul, %sub1
+ ret float %mul2
+; CHECK: @test7
+; CHECK: fsub float -0.000000e+00, %x
+}