scanon created this revision. scanon added reviewers: hfinkel, resistor, lhames. scanon added a subscriber: cfe-commits.
r253269 exposed a pre-existing issue in tryEmitFMulAdd, where we would assert if a fusable operation had operands with multiple uses (we didn't see it previously because FP_CONTRACT was off by default). Fix this issue by changing the assert into an early-out where we simply won't try to fuse. Once this is done, we can try again at enabling FP_CONTRACT ON as a default. http://reviews.llvm.org/D14891 Files: lib/CodeGen/CGExprScalar.cpp Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -2563,22 +2563,19 @@ if (CGF.CGM.getCodeGenOpts().getFPContractMode() != CodeGenOptions::FPC_On) return nullptr; - // We have a potentially fusable op. Look for a mul on one of the operands. + // We have a potentially fusable op. Look for a mul on one of the operands + // that does not have any other uses. if (llvm::BinaryOperator* LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) { - if (LHSBinOp->getOpcode() == llvm::Instruction::FMul) { - assert(LHSBinOp->getNumUses() == 0 && - "Operations with multiple uses shouldn't be contracted."); + if (LHSBinOp->getOpcode() == llvm::Instruction::FMul && + LHSBinOp->hasNUses(0)) return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub); - } - } else if (llvm::BinaryOperator* RHSBinOp = - dyn_cast<llvm::BinaryOperator>(op.RHS)) { - if (RHSBinOp->getOpcode() == llvm::Instruction::FMul) { - assert(RHSBinOp->getNumUses() == 0 && - "Operations with multiple uses shouldn't be contracted."); + } + if (llvm::BinaryOperator* RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) { + if (RHSBinOp->getOpcode() == llvm::Instruction::FMul && + RHSBinOp->hasNUses(0)) return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false); - } } - + return nullptr; }
Index: lib/CodeGen/CGExprScalar.cpp =================================================================== --- lib/CodeGen/CGExprScalar.cpp +++ lib/CodeGen/CGExprScalar.cpp @@ -2563,22 +2563,19 @@ if (CGF.CGM.getCodeGenOpts().getFPContractMode() != CodeGenOptions::FPC_On) return nullptr; - // We have a potentially fusable op. Look for a mul on one of the operands. + // We have a potentially fusable op. Look for a mul on one of the operands + // that does not have any other uses. if (llvm::BinaryOperator* LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) { - if (LHSBinOp->getOpcode() == llvm::Instruction::FMul) { - assert(LHSBinOp->getNumUses() == 0 && - "Operations with multiple uses shouldn't be contracted."); + if (LHSBinOp->getOpcode() == llvm::Instruction::FMul && + LHSBinOp->hasNUses(0)) return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub); - } - } else if (llvm::BinaryOperator* RHSBinOp = - dyn_cast<llvm::BinaryOperator>(op.RHS)) { - if (RHSBinOp->getOpcode() == llvm::Instruction::FMul) { - assert(RHSBinOp->getNumUses() == 0 && - "Operations with multiple uses shouldn't be contracted."); + } + if (llvm::BinaryOperator* RHSBinOp = dyn_cast<llvm::BinaryOperator>(op.RHS)) { + if (RHSBinOp->getOpcode() == llvm::Instruction::FMul && + RHSBinOp->hasNUses(0)) return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false); - } } - + return nullptr; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits