aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Ilseman <milseman@apple.com>2013-02-07 01:40:15 +0000
committerMichael Ilseman <milseman@apple.com>2013-02-07 01:40:15 +0000
commit0fae64fde0a75cb2b36a92fb249f88d6a4378202 (patch)
tree9d795c08ce2197c3ee241ac653b5499dae2137a4
parent9f41a5c7fa44f85c6dd9a69990d50e110ad5f731 (diff)
Preserve fast-math flags after reassociation and commutation. Update test cases
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174571 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstructionCombining.cpp25
-rw-r--r--test/Transforms/InstCombine/fast-math.ll8
2 files changed, 24 insertions, 9 deletions
diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp
index dc7fe5cf6b..c6115e3e91 100644
--- a/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -162,6 +162,21 @@ static bool MaintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
return !Overflow;
}
+/// Conservatively clears subclassOptionalData after a reassociation or
+/// commutation. We preserve fast-math flags when applicable as they can be
+/// preserved.
+static void ClearSubclassDataAfterReassociation(BinaryOperator &I) {
+ FPMathOperator *FPMO = dyn_cast<FPMathOperator>(&I);
+ if (!FPMO) {
+ I.clearSubclassOptionalData();
+ return;
+ }
+
+ FastMathFlags FMF = I.getFastMathFlags();
+ I.clearSubclassOptionalData();
+ I.setFastMathFlags(FMF);
+}
+
/// SimplifyAssociativeOrCommutative - This performs a few simplifications for
/// operators which are associative or commutative:
//
@@ -219,7 +234,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
I.clearSubclassOptionalData();
I.setHasNoSignedWrap(true);
} else {
- I.clearSubclassOptionalData();
+ ClearSubclassDataAfterReassociation(I);
}
Changed = true;
@@ -241,7 +256,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
I.setOperand(1, C);
// Conservatively clear the optional flags, since they may not be
// preserved by the reassociation.
- I.clearSubclassOptionalData();
+ ClearSubclassDataAfterReassociation(I);
Changed = true;
++NumReassoc;
continue;
@@ -263,7 +278,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
I.setOperand(1, B);
// Conservatively clear the optional flags, since they may not be
// preserved by the reassociation.
- I.clearSubclassOptionalData();
+ ClearSubclassDataAfterReassociation(I);
Changed = true;
++NumReassoc;
continue;
@@ -283,7 +298,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
I.setOperand(1, V);
// Conservatively clear the optional flags, since they may not be
// preserved by the reassociation.
- I.clearSubclassOptionalData();
+ ClearSubclassDataAfterReassociation(I);
Changed = true;
++NumReassoc;
continue;
@@ -310,7 +325,7 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
I.setOperand(1, Folded);
// Conservatively clear the optional flags, since they may not be
// preserved by the reassociation.
- I.clearSubclassOptionalData();
+ ClearSubclassDataAfterReassociation(I);
Changed = true;
continue;
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index 4de0c8234f..c97bd28222 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -7,7 +7,7 @@ define float @fold(float %a) {
%mul1 = fmul fast float %mul, 0x4002666660000000
ret float %mul1
; CHECK: @fold
-; CHECK: fmul float %a, 0x4006147AE0000000
+; CHECK: fmul fast float %a, 0x4006147AE0000000
}
; Same testing-case as the one used in fold() except that the operators have
@@ -22,7 +22,7 @@ define float @notfold(float %a) {
define float @fold2(float %a) {
; CHECK: @fold2
-; CHECK: fmul float %a, 0x4006147AE0000000
+; CHECK: fmul fast float %a, 0x4006147AE0000000
%mul = fmul float %a, 0x3FF3333340000000
%mul1 = fmul fast float %mul, 0x4002666660000000
ret float %mul1
@@ -54,7 +54,7 @@ define float @fold5(float %f1, float %f2) {
%add1 = fadd fast float %add, 5.000000e+00
ret float %add1
; CHECK: @fold5
-; CHECK: fadd float %f1, 9.000000e+00
+; CHECK: fadd fast float %f1, 9.000000e+00
}
; (X + X) + X => 3.0 * X
@@ -107,7 +107,7 @@ define float @fold10(float %f1, float %f2) {
%t3 = fadd fast float %t1, %t2
ret float %t3
; CHECK: @fold10
-; CHECK: %t3 = fadd float %t2, -1.000000e+00
+; CHECK: %t3 = fadd fast float %t2, -1.000000e+00
; CHECK: ret float %t3
}