Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -794,6 +794,11 @@ if (Opnd->isConstant()) continue; + // The constant check above is really for a few special constant + // coefficients. + if (isa(Opnd->getSymVal())) + continue; + const FAddendCoef &CE = Opnd->getCoef(); if (CE.isMinusOne() || CE.isMinusTwo()) NegOpndNum++; Index: test/Transforms/InstCombine/fsub.ll =================================================================== --- test/Transforms/InstCombine/fsub.ll +++ test/Transforms/InstCombine/fsub.ll @@ -21,3 +21,47 @@ 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 +}