]> granicus.if.org Git - llvm/commitdiff
InstCombine: Fix assert when reassociating fsub with undef
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 24 Apr 2017 17:24:37 +0000 (17:24 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Mon, 24 Apr 2017 17:24:37 +0000 (17:24 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301199 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAddSub.cpp
test/Transforms/InstCombine/fsub.ll

index 05f34e9eaa0a3862a7154af1a5b59e3f3b87741d..e946acf84f5766dcfae632f9c43f2b8d3a5c1bcd 100644 (file)
@@ -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++;
index af2fadd2867bc95c359615259cf011f180076fb8..6b62f5dd7e3899f8890d4ac380dd4d92da8f1869 100644 (file)
@@ -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
+}