mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 14:40:25 +00:00
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:
parent
b3e6b04aea
commit
c5a4c25b87
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user