Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1995,8 +1995,17 @@ Constant *C2; // C-(X+C2) --> (C-C2)-X - if (match(Op1, m_Add(m_Value(X), m_ImmConstant(C2)))) - return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); + if (match(Op1, m_Add(m_Value(X), m_ImmConstant(C2)))) { + // C-C2 never overflow, and C-(X+C2), (X+C2) has NSW + // => (C-C2)-X can have NSW + bool WillNotSOV = willNotOverflowSignedSub(C, C2, I); + BinaryOperator *Res = + BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X); + auto *OBO1 = cast(Op1); + Res->setHasNoSignedWrap(I.hasNoSignedWrap() && OBO1->hasNoSignedWrap() && + WillNotSOV); + return Res; + } } auto TryToNarrowDeduceFlags = [this, &I, &Op0, &Op1]() -> Instruction * { Index: llvm/test/Transforms/InstCombine/addsub-constant-folding.ll =================================================================== --- llvm/test/Transforms/InstCombine/addsub-constant-folding.ll +++ llvm/test/Transforms/InstCombine/addsub-constant-folding.ll @@ -134,7 +134,7 @@ define i32 @add_nsw_const_const_sub_nsw(i32 %arg) { ; CHECK-LABEL: @add_nsw_const_const_sub_nsw( -; CHECK-NEXT: [[T1:%.*]] = sub i32 -2147483648, [[ARG:%.*]] +; CHECK-NEXT: [[T1:%.*]] = sub nsw i32 -2147483648, [[ARG:%.*]] ; CHECK-NEXT: ret i32 [[T1]] ; %t0 = add nsw i32 %arg, 1