Fix a bug in instcombine for fmul in fast math mode.

The instcombine recognized pattern looks like:
a = b * c
d = a +/- Cst
or
a = b * c
d = Cst +/- a

When creating the new operands for fadd or fsub instruction following the related fmul, the first operand was created with the second original operand (M0 was created with C1) and the second with the first (M1 with Opnd0).

The fix consists in creating the new operands with the appropriate original operand, i.e., M0 with Opnd0 and M1 with C1.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176300 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Quentin Colombet 2013-02-28 21:12:40 +00:00
parent b3e6b04aea
commit c5a4c25b87
2 changed files with 14 additions and 3 deletions

View File

@ -402,7 +402,7 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
return ReplaceInstUsesWith(I, V);
}
// (MDC +/- C1) * C2 => (MDC * C2) +/- (C1 * C2)
// (MDC +/- C1) * C => (MDC * C) +/- (C1 * C)
Instruction *FAddSub = dyn_cast<Instruction>(Op0);
if (FAddSub &&
(FAddSub->getOpcode() == Instruction::FAdd ||
@ -420,8 +420,8 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
if (C1 && C1->getValueAPF().isNormal() &&
isFMulOrFDivWithConstant(Opnd0)) {
Value *M0 = ConstantExpr::getFMul(C1, C);
Value *M1 = isNormalFp(cast<ConstantFP>(M0)) ?
Value *M1 = ConstantExpr::getFMul(C1, C);
Value *M0 = isNormalFp(cast<ConstantFP>(M1)) ?
foldFMulConst(cast<Instruction>(Opnd0), C, &I) :
0;
if (M0 && M1) {

View File

@ -172,6 +172,17 @@ define double @fmul_distribute3(double %f1) {
; CHECK: fmul fast double %t2, 0x10000000000000
}
; ((X*C1) + C2) * C3 => (X * (C1*C3)) + (C2*C3) (i.e. distribution)
define float @fmul_distribute4(float %f1) {
%t1 = fmul float %f1, 6.0e+3
%t2 = fsub float 2.0e+3, %t1
%t3 = fmul fast float %t2, 5.0e+3
ret float %t3
; CHECK: @fmul_distribute4
; CHECK: %1 = fmul fast float %f1, 3.000000e+07
; CHECK: %t3 = fsub fast float 1.000000e+07, %1
}
; C1/X * C2 => (C1*C2) / X
define float @fmul2(float %f1) {
%t1 = fdiv float 2.0e+3, %f1