diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -229,6 +229,12 @@ ConstantInt *CI; if (match(V, m_NUWAdd(m_Value(Op0), m_ConstantInt(CI)))) return {{CI->getSExtValue(), nullptr}, {1, Op0}}; + if (match(V, m_Add(m_Value(Op0), m_ConstantInt(CI))) && CI->isNegative()) { + Preconditions.emplace_back( + CmpInst::ICMP_UGE, Op0, + ConstantInt::get(Op0->getType(), CI->getSExtValue() * -1)); + return {{CI->getSExtValue(), nullptr}, {1, Op0}}; + } if (match(V, m_NUWAdd(m_Value(Op0), m_Value(Op1)))) return {{0, nullptr}, {1, Op0}, {1, Op1}}; diff --git a/llvm/test/Transforms/ConstraintElimination/wrapping-math.ll b/llvm/test/Transforms/ConstraintElimination/wrapping-math.ll --- a/llvm/test/Transforms/ConstraintElimination/wrapping-math.ll +++ b/llvm/test/Transforms/ConstraintElimination/wrapping-math.ll @@ -22,7 +22,7 @@ ; CHECK: then: ; CHECK-NEXT: [[SUB_1:%.*]] = add i8 [[A]], -1 ; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[SUB_1]], 0 -; CHECK-NEXT: ret i1 [[C_1]] +; CHECK-NEXT: ret i1 true ; CHECK: else: ; CHECK-NEXT: [[SUB_2:%.*]] = add i8 [[A]], -1 ; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[SUB_2]], 0 @@ -85,7 +85,7 @@ ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[SUB_1]], [[A]] ; CHECK-NEXT: [[SUB_2:%.*]] = add i8 [[B]], -2 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i8 [[SUB_2]], [[A]] -; CHECK-NEXT: [[XOR_1:%.*]] = xor i1 [[T_1]], [[C_2]] +; CHECK-NEXT: [[XOR_1:%.*]] = xor i1 true, [[C_2]] ; CHECK-NEXT: ret i1 [[XOR_1]] ; CHECK: exit.1: ; CHECK-NEXT: [[SUB_3:%.*]] = add i8 [[B]], -1 @@ -133,9 +133,9 @@ ; CHECK: if.end: ; CHECK-NEXT: [[T_1:%.*]] = icmp ult i8 [[SUB_1]], [[B]] ; CHECK-NEXT: [[T_2:%.*]] = icmp ult i8 [[SUB_2]], [[B]] -; CHECK-NEXT: [[XOR_1:%.*]] = xor i1 [[T_1]], [[T_2]] +; CHECK-NEXT: [[XOR_1:%.*]] = xor i1 true, true ; CHECK-NEXT: [[T_3:%.*]] = icmp ult i8 [[SUB_3]], [[B]] -; CHECK-NEXT: [[XOR_2:%.*]] = xor i1 [[XOR_1]], [[T_3]] +; CHECK-NEXT: [[XOR_2:%.*]] = xor i1 [[XOR_1]], true ; CHECK-NEXT: [[C_1:%.*]] = icmp ult i8 [[SUB_4]], [[B]] ; CHECK-NEXT: [[XOR_3:%.*]] = xor i1 [[XOR_2]], [[C_1]] ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i8 [[ADD_1]], [[B]]