summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2017-04-24 17:24:37 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2017-04-24 17:24:37 +0000
commit02907f30397129dbebb2b633135c638a25c99463 (patch)
tree46232784e44651875909f7c80afa6c8df3dc4b96
parent8b37326ae2363c51ca33362cd49b28b9d624750e (diff)
downloadbcm5719-llvm-02907f30397129dbebb2b633135c638a25c99463.tar.gz
bcm5719-llvm-02907f30397129dbebb2b633135c638a25c99463.zip
InstCombine: Fix assert when reassociating fsub with undef
There is logic to track the expected number of instructions produced. It thought in this case an instruction would be necessary to negate the result, but here it folded into a ConstantExpr fneg when the non-undef value operand was cancelled out by the second fsub. I'm not sure why we don't fold constant FP ops with undef currently, but I think that would also avoid this problem. llvm-svn: 301199
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp5
-rw-r--r--llvm/test/Transforms/InstCombine/fsub.ll44
2 files changed, 49 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 05f34e9eaa0..e946acf84f5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -794,6 +794,11 @@ unsigned FAddCombine::calcInstrNumber(const AddendVect &Opnds) {
if (Opnd->isConstant())
continue;
+ // The constant check above is really for a few special constant
+ // coefficients.
+ if (isa<UndefValue>(Opnd->getSymVal()))
+ continue;
+
const FAddendCoef &CE = Opnd->getCoef();
if (CE.isMinusOne() || CE.isMinusTwo())
NegOpndNum++;
diff --git a/llvm/test/Transforms/InstCombine/fsub.ll b/llvm/test/Transforms/InstCombine/fsub.ll
index af2fadd2867..6b62f5dd7e3 100644
--- a/llvm/test/Transforms/InstCombine/fsub.ll
+++ b/llvm/test/Transforms/InstCombine/fsub.ll
@@ -21,3 +21,47 @@ define double @test2(double %x, double %y) nounwind {
ret double %t2
}
+
+; CHECK-LABEL: @fsub_undef(
+; CHECK: %sub = fsub float %val, undef
+define float @fsub_undef(float %val) {
+bb:
+ %sub = fsub float %val, undef
+ ret float %sub
+}
+
+; XXX - Why doesn't this fold to undef?
+; CHECK-LABEL: @fsub_fast_undef(
+; CHCK: %sub = fsub fast float %val, undef
+define float @fsub_fast_undef(float %val) {
+bb:
+ %sub = fsub fast float %val, undef
+ ret float %sub
+}
+
+; CHECK-LABEL: @fneg_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @fneg_undef(float %val) {
+bb:
+ %sub = fsub float -0.0, undef
+ ret float %sub
+}
+
+; CHECK-LABEL: @fneg_fast_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @fneg_fast_undef(float %val) {
+bb:
+ %sub = fsub fast float -0.0, undef
+ ret float %sub
+}
+
+; This folds to a constant expression, which produced 0 instructions
+; contrary to the expected one for negation.
+; CHECK-LABEL: @inconsistent_numbers_fsub_undef(
+; CHECK: ret float fsub (float -0.000000e+00, float undef)
+define float @inconsistent_numbers_fsub_undef(float %val) {
+bb:
+ %sub0 = fsub fast float %val, undef
+ %sub1 = fsub fast float %sub0, %val
+ ret float %sub1
+}
OpenPOWER on IntegriCloud