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