@@ -1047,89 +1047,28 @@ static Instruction *canonicalizeMinMaxWithConstant(SelectInst &Sel,
1047
1047
return &Sel;
1048
1048
}
1049
1049
1050
- // / There are many select variants for each of ABS/NABS.
1051
- // / In matchSelectPattern(), there are different compare constants, compare
1052
- // / predicates/operands and select operands.
1053
- // / In isKnownNegation(), there are different formats of negated operands.
1054
- // / Canonicalize all these variants to 1 pattern.
1055
- // / This makes CSE more likely.
1056
1050
static Instruction *canonicalizeAbsNabs (SelectInst &Sel, ICmpInst &Cmp,
1057
1051
InstCombinerImpl &IC) {
1058
1052
if (!Cmp.hasOneUse () || !isa<Constant>(Cmp.getOperand (1 )))
1059
1053
return nullptr ;
1060
1054
1061
- // Choose a sign-bit check for the compare (likely simpler for codegen).
1062
- // ABS: (X <s 0) ? -X : X
1063
- // NABS: (X <s 0) ? X : -X
1064
1055
Value *LHS, *RHS;
1065
1056
SelectPatternFlavor SPF = matchSelectPattern (&Sel, LHS, RHS).Flavor ;
1066
1057
if (SPF != SelectPatternFlavor::SPF_ABS &&
1067
1058
SPF != SelectPatternFlavor::SPF_NABS)
1068
1059
return nullptr ;
1069
1060
1070
- Value *TVal = Sel.getTrueValue ();
1071
- Value *FVal = Sel.getFalseValue ();
1072
- assert (isKnownNegation (TVal, FVal) &&
1073
- " Unexpected result from matchSelectPattern" );
1074
-
1075
- // The compare may use the negated abs()/nabs() operand, or it may use
1076
- // negation in non-canonical form such as: sub A, B.
1077
- bool CmpUsesNegatedOp = match (Cmp.getOperand (0 ), m_Neg (m_Specific (TVal))) ||
1078
- match (Cmp.getOperand (0 ), m_Neg (m_Specific (FVal)));
1079
-
1080
- bool CmpCanonicalized = !CmpUsesNegatedOp &&
1081
- match (Cmp.getOperand (1 ), m_ZeroInt ()) &&
1082
- Cmp.getPredicate () == ICmpInst::ICMP_SLT;
1083
- bool RHSCanonicalized = match (RHS, m_Neg (m_Specific (LHS)));
1084
-
1085
- // Is this already canonical?
1086
- if (CmpCanonicalized && RHSCanonicalized)
1087
- return nullptr ;
1088
-
1089
- // If RHS is not canonical but is used by other instructions, don't
1090
- // canonicalize it and potentially increase the instruction count.
1091
- if (!RHSCanonicalized)
1092
- if (!(RHS->hasOneUse () || (RHS->hasNUses (2 ) && CmpUsesNegatedOp)))
1093
- return nullptr ;
1061
+ bool IntMinIsPoison = match (RHS, m_NSWNeg (m_Specific (LHS)));
1062
+ Constant *IntMinIsPoisonC =
1063
+ ConstantInt::get (Type::getInt1Ty (Sel.getContext ()), IntMinIsPoison);
1064
+ Instruction *Abs =
1065
+ IC.Builder .CreateBinaryIntrinsic (Intrinsic::abs, LHS, IntMinIsPoisonC);
1094
1066
1095
- // Create the canonical compare: icmp slt LHS 0.
1096
- if (!CmpCanonicalized) {
1097
- Cmp.setPredicate (ICmpInst::ICMP_SLT);
1098
- Cmp.setOperand (1 , ConstantInt::getNullValue (Cmp.getOperand (0 )->getType ()));
1099
- if (CmpUsesNegatedOp)
1100
- Cmp.setOperand (0 , LHS);
1101
- }
1102
-
1103
- // Create the canonical RHS: RHS = sub (0, LHS).
1104
- if (!RHSCanonicalized) {
1105
- assert (RHS->hasOneUse () && " RHS use number is not right" );
1106
- RHS = IC.Builder .CreateNeg (LHS);
1107
- if (TVal == LHS) {
1108
- // Replace false value.
1109
- IC.replaceOperand (Sel, 2 , RHS);
1110
- FVal = RHS;
1111
- } else {
1112
- // Replace true value.
1113
- IC.replaceOperand (Sel, 1 , RHS);
1114
- TVal = RHS;
1115
- }
1116
- }
1067
+ if (SPF == SelectPatternFlavor::SPF_NABS)
1068
+ return IntMinIsPoison ? BinaryOperator::CreateNSWNeg (Abs)
1069
+ : BinaryOperator::CreateNeg (Abs);
1117
1070
1118
- // If the select operands do not change, we're done.
1119
- if (SPF == SelectPatternFlavor::SPF_NABS) {
1120
- if (TVal == LHS)
1121
- return &Sel;
1122
- assert (FVal == LHS && " Unexpected results from matchSelectPattern" );
1123
- } else {
1124
- if (FVal == LHS)
1125
- return &Sel;
1126
- assert (TVal == LHS && " Unexpected results from matchSelectPattern" );
1127
- }
1128
-
1129
- // We are swapping the select operands, so swap the metadata too.
1130
- Sel.swapValues ();
1131
- Sel.swapProfMetadata ();
1132
- return &Sel;
1071
+ return IC.replaceInstUsesWith (Sel, Abs);
1133
1072
}
1134
1073
1135
1074
// / If we have a select with an equality comparison, then we know the value in
0 commit comments