llvm.org GIT mirror llvm / e357c8b
[InstSimplify] fold select (fcmp X, Y), X, Y This is NFCI for InstCombine because it calls InstSimplify, so I left the tests for this transform there. As noted in the code comment, we can allow this fold more often by using FMF and/or value tracking. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346169 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 11 months ago
3 changed file(s) with 35 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
38733873 return nullptr;
38743874 }
38753875
3876 /// Try to simplify a select instruction when its condition operand is a
3877 /// floating-point comparison.
3878 static Value *simplifySelectWithFCmp(Value *Cond, Value *T, Value *F) {
3879 FCmpInst::Predicate Pred;
3880 if (!match(Cond, m_FCmp(Pred, m_Specific(T), m_Specific(F))) &&
3881 !match(Cond, m_FCmp(Pred, m_Specific(F), m_Specific(T))))
3882 return nullptr;
3883
3884 // TODO: The transform may not be valid with -0.0. An incomplete way of
3885 // testing for that possibility is to check if at least one operand is a
3886 // non-zero constant.
3887 const APFloat *C;
3888 if ((match(T, m_APFloat(C)) && C->isNonZero()) ||
3889 (match(F, m_APFloat(C)) && C->isNonZero())) {
3890 // (T == F) ? T : F --> F
3891 // (F == T) ? T : F --> F
3892 if (Pred == FCmpInst::FCMP_OEQ)
3893 return F;
3894
3895 // (T != F) ? T : F --> T
3896 // (F != T) ? T : F --> T
3897 if (Pred == FCmpInst::FCMP_UNE)
3898 return T;
3899 }
3900
3901 return nullptr;
3902 }
3903
38763904 /// Given operands for a SelectInst, see if we can fold the result.
38773905 /// If not, this returns null.
38783906 static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
39073935
39083936 if (Value *V =
39093937 simplifySelectWithICmpCond(Cond, TrueVal, FalseVal, Q, MaxRecurse))
3938 return V;
3939
3940 if (Value *V = simplifySelectWithFCmp(Cond, TrueVal, FalseVal))
39103941 return V;
39113942
39123943 if (Value *V = foldSelectWithBinaryOp(Cond, TrueVal, FalseVal))
16591659 // See if we are selecting two values based on a comparison of the two values.
16601660 if (FCmpInst *FCI = dyn_cast(CondVal)) {
16611661 if (FCI->getOperand(0) == TrueVal && FCI->getOperand(1) == FalseVal) {
1662 // Transform (X == Y) ? X : Y -> Y
1663 if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
1664 // This is not safe in general for floating point:
1665 // consider X== -0, Y== +0.
1666 // It becomes safe if either operand is a nonzero constant.
1667 ConstantFP *CFPt, *CFPf;
1668 if (((CFPt = dyn_cast(TrueVal)) &&
1669 !CFPt->getValueAPF().isZero()) ||
1670 ((CFPf = dyn_cast(FalseVal)) &&
1671 !CFPf->getValueAPF().isZero()))
1672 return replaceInstUsesWith(SI, FalseVal);
1673 }
1674 // Transform (X une Y) ? X : Y -> X
1675 if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
1676 // This is not safe in general for floating point:
1677 // consider X== -0, Y== +0.
1678 // It becomes safe if either operand is a nonzero constant.
1679 ConstantFP *CFPt, *CFPf;
1680 if (((CFPt = dyn_cast(TrueVal)) &&
1681 !CFPt->getValueAPF().isZero()) ||
1682 ((CFPf = dyn_cast(FalseVal)) &&
1683 !CFPf->getValueAPF().isZero()))
1684 return replaceInstUsesWith(SI, TrueVal);
1685 }
1686
16871662 // Canonicalize to use ordered comparisons by swapping the select
16881663 // operands.
16891664 //
17021677
17031678 // NOTE: if we wanted to, this is where to detect MIN/MAX
17041679 } else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
1705 // Transform (X == Y) ? Y : X -> X
1706 if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
1707 // This is not safe in general for floating point:
1708 // consider X== -0, Y== +0.
1709 // It becomes safe if either operand is a nonzero constant.
1710 ConstantFP *CFPt, *CFPf;
1711 if (((CFPt = dyn_cast(TrueVal)) &&
1712 !CFPt->getValueAPF().isZero()) ||
1713 ((CFPf = dyn_cast(FalseVal)) &&
1714 !CFPf->getValueAPF().isZero()))
1715 return replaceInstUsesWith(SI, FalseVal);
1716 }
1717 // Transform (X une Y) ? Y : X -> Y
1718 if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
1719 // This is not safe in general for floating point:
1720 // consider X== -0, Y== +0.
1721 // It becomes safe if either operand is a nonzero constant.
1722 ConstantFP *CFPt, *CFPf;
1723 if (((CFPt = dyn_cast(TrueVal)) &&
1724 !CFPt->getValueAPF().isZero()) ||
1725 ((CFPf = dyn_cast(FalseVal)) &&
1726 !CFPf->getValueAPF().isZero()))
1727 return replaceInstUsesWith(SI, TrueVal);
1728 }
1729
17301680 // Canonicalize to use ordered comparisons by swapping the select
17311681 // operands.
17321682 //
44
55 define double @oeq(double %x) {
66 ; CHECK-LABEL: @oeq(
7 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[X:%.*]], 4.200000e+01
8 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], double [[X]], double 4.200000e+01
9 ; CHECK-NEXT: ret double [[COND]]
7 ; CHECK-NEXT: ret double 4.200000e+01
108 ;
119 %cmp = fcmp oeq double %x, 42.0
1210 %cond = select i1 %cmp, double %x, double 42.0
1715
1816 define float @oeq_swapped(float %x) {
1917 ; CHECK-LABEL: @oeq_swapped(
20 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[X:%.*]], 4.200000e+01
21 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], float 4.200000e+01, float [[X]]
22 ; CHECK-NEXT: ret float [[COND]]
18 ; CHECK-NEXT: ret float [[X:%.*]]
2319 ;
2420 %cmp = fcmp oeq float %x, 42.0
2521 %cond = select i1 %cmp, float 42.0, float %x
3329
3430 define double @une(double %x) {
3531 ; CHECK-LABEL: @une(
36 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[X:%.*]], 4.200000e+01
37 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], double [[X]], double 4.200000e+01
38 ; CHECK-NEXT: ret double [[COND]]
32 ; CHECK-NEXT: ret double [[X:%.*]]
3933 ;
4034 %cmp = fcmp une double %x, 42.0
4135 %cond = select i1 %cmp, double %x, double 42.0
4640
4741 define double @une_swapped(double %x) {
4842 ; CHECK-LABEL: @une_swapped(
49 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[X:%.*]], 4.200000e+01
50 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], double 4.200000e+01, double [[X]]
51 ; CHECK-NEXT: ret double [[COND]]
43 ; CHECK-NEXT: ret double 4.200000e+01
5244 ;
5345 %cmp = fcmp une double %x, 42.0
5446 %cond = select i1 %cmp, double 42.0, double %x