[InstSimplify] Fold away ord/uno fcmps when nnan is present.

This is important to fold away the slow case of complex multiplies
emitted by clang.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241911 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2015-07-10 14:02:02 +00:00
parent ee0d992b07
commit b0927bee8e
4 changed files with 35 additions and 11 deletions

View File

@ -212,7 +212,7 @@ namespace llvm {
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout &DL,
FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,

View File

@ -3046,7 +3046,8 @@ Value *llvm::SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const Query &Q, unsigned MaxRecurse) {
FastMathFlags FMF, const Query &Q,
unsigned MaxRecurse) {
CmpInst::Predicate Pred = (CmpInst::Predicate)Predicate;
assert(CmpInst::isFPPredicate(Pred) && "Not an FP compare!");
@ -3065,6 +3066,14 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
if (Pred == FCmpInst::FCMP_TRUE)
return ConstantInt::get(GetCompareTy(LHS), 1);
// UNO/ORD predicates can be trivially folded if NaNs are ignored.
if (FMF.noNaNs()) {
if (Pred == FCmpInst::FCMP_UNO)
return ConstantInt::get(GetCompareTy(LHS), 0);
if (Pred == FCmpInst::FCMP_ORD)
return ConstantInt::get(GetCompareTy(LHS), 1);
}
// fcmp pred x, undef and fcmp pred undef, x
// fold to true if unordered, false if ordered
if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS)) {
@ -3151,12 +3160,12 @@ static Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
}
Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout &DL,
FastMathFlags FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI,
const DominatorTree *DT, AssumptionCache *AC,
const Instruction *CxtI) {
return ::SimplifyFCmpInst(Predicate, LHS, RHS, Query(DL, TLI, DT, AC, CxtI),
RecursionLimit);
return ::SimplifyFCmpInst(Predicate, LHS, RHS, FMF,
Query(DL, TLI, DT, AC, CxtI), RecursionLimit);
}
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
@ -3670,7 +3679,7 @@ static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const Query &Q, unsigned MaxRecurse) {
if (CmpInst::isIntPredicate((CmpInst::Predicate)Predicate))
return SimplifyICmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
return SimplifyFCmpInst(Predicate, LHS, RHS, Q, MaxRecurse);
return SimplifyFCmpInst(Predicate, LHS, RHS, FastMathFlags(), Q, MaxRecurse);
}
Value *llvm::SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
@ -3900,9 +3909,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const DataLayout &DL,
I->getOperand(1), DL, TLI, DT, AC, I);
break;
case Instruction::FCmp:
Result =
SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(), I->getOperand(0),
I->getOperand(1), DL, TLI, DT, AC, I);
Result = SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
I->getOperand(0), I->getOperand(1),
I->getFastMathFlags(), DL, TLI, DT, AC, I);
break;
case Instruction::Select:
Result = SimplifySelectInst(I->getOperand(0), I->getOperand(1),

View File

@ -3928,8 +3928,8 @@ Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
if (Value *V =
SimplifyFCmpInst(I.getPredicate(), Op0, Op1, DL, TLI, DT, AC, &I))
if (Value *V = SimplifyFCmpInst(I.getPredicate(), Op0, Op1,
I.getFastMathFlags(), DL, TLI, DT, AC, &I))
return ReplaceInstUsesWith(I, V);
// Simplify 'fcmp pred X, X'

View File

@ -58,3 +58,18 @@ define i1 @orderedLessZeroPowi(double,double) {
ret i1 %olt
}
define i1 @nonans1(double %in1, double %in2) {
%cmp = fcmp nnan uno double %in1, %in2
ret i1 %cmp
; CHECK-LABEL: @nonans1
; CHECK-NEXT: ret i1 false
}
define i1 @nonans2(double %in1, double %in2) {
%cmp = fcmp nnan ord double %in1, %in2
ret i1 %cmp
; CHECK-LABEL: @nonans2
; CHECK-NEXT: ret i1 true
}