@@ -1224,11 +1224,32 @@ static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
12241224 return false ;
12251225}
12261226
1227+ static bool isSaveToNarrow (unsigned opc, uint64_t num1, uint64_t num2) {
1228+ if (num1 > 0xffffffff || num2 > 0xffffffff ) {
1229+ // if `num > 0xffffffff`, then `%and = and i64 %a, num` may or may not have
1230+ // higher 32bit set. Which cause truncate possibly lose infomation
1231+ return false ;
1232+ }
1233+ switch (opc) {
1234+ // If `%and = and i64 %a, num` where num <= 0xffffffff, then `%and` must be
1235+ // positive.
1236+ // Since add and mul both increasing function on positive integer domain and
1237+ // `%ai <= numi`, then if `(num1 op num2) <= 0xffffffff` we have `%a1 + %a2 <=
1238+ // 0xffffffff`
1239+ case Instruction::Add:
1240+ return (num1 + num2) <= 0xffffffff ;
1241+ case Instruction::Mul:
1242+ return (num1 * num2) <= 0xffffffff ;
1243+ break ;
1244+ }
1245+
1246+ return false ;
1247+ }
1248+
12271249static bool tryNarrowMathIfNoOverflow (Instruction &I,
12281250 TargetTransformInfo &TTI) {
12291251 unsigned opc = I.getOpcode ();
1230- if (opc != Instruction::Add && opc != Instruction::Sub &&
1231- opc != Instruction::Mul) {
1252+ if (opc != Instruction::Add && opc != Instruction::Mul) {
12321253 return false ;
12331254 }
12341255 LLVMContext &ctx = I.getContext ();
@@ -1252,10 +1273,9 @@ static bool tryNarrowMathIfNoOverflow(Instruction &I,
12521273 Value *X;
12531274 if ((match (I.getOperand (0 ), m_And (m_Value (X), m_ConstantInt (AndConst0))) ||
12541275 match (I.getOperand (0 ), m_And (m_ConstantInt (AndConst0), m_Value (X)))) &&
1255- AndConst0 <= 2147483647 &&
12561276 (match (I.getOperand (1 ), m_And (m_Value (X), m_ConstantInt (AndConst1))) ||
12571277 match (I.getOperand (1 ), m_And (m_ConstantInt (AndConst1), m_Value (X)))) &&
1258- AndConst1 <= 2147483647 ) {
1278+ isSaveToNarrow (opc, AndConst0, AndConst1) ) {
12591279 IRBuilder<> Builder (&I);
12601280 Value *trun0 = Builder.CreateTrunc (I.getOperand (0 ), i32type);
12611281 Value *trun1 = Builder.CreateTrunc (I.getOperand (1 ), i32type);
0 commit comments