mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-04 06:09:05 +00:00
InstCombine: Annotate sub with nuw when we prove it's safe
We can prove that a 'sub' can be a 'sub nuw' if the left-hand side is negative and the right-hand side is non-negative. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216045 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
78832c6e7d
commit
99e941fd9a
@ -251,6 +251,7 @@ private:
|
||||
bool WillNotOverflowSignedAdd(Value *LHS, Value *RHS);
|
||||
bool WillNotOverflowUnsignedAdd(Value *LHS, Value *RHS);
|
||||
bool WillNotOverflowSignedSub(Value *LHS, Value *RHS);
|
||||
bool WillNotOverflowUnsignedSub(Value *LHS, Value *RHS);
|
||||
Value *EmitGEPOffset(User *GEP);
|
||||
Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
|
||||
Value *EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask);
|
||||
|
@ -988,6 +988,20 @@ bool InstCombiner::WillNotOverflowSignedSub(Value *LHS, Value *RHS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Return true if we can prove that:
|
||||
/// (sub LHS, RHS) === (sub nuw LHS, RHS)
|
||||
bool InstCombiner::WillNotOverflowUnsignedSub(Value *LHS, Value *RHS) {
|
||||
// If the LHS is negative and the RHS is non-negative, no unsigned wrap.
|
||||
bool LHSKnownNonNegative, LHSKnownNegative;
|
||||
bool RHSKnownNonNegative, RHSKnownNegative;
|
||||
ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, DL, 0);
|
||||
ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, DL, 0);
|
||||
if (LHSKnownNegative && RHSKnownNonNegative)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if any operand is negative and we can convert add to sub.
|
||||
// This function checks for following negative patterns
|
||||
// ADD(XOR(OR(Z, NOT(C)), C)), 1) == NEG(AND(Z, C))
|
||||
@ -1660,6 +1674,10 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
|
||||
Changed = true;
|
||||
I.setHasNoSignedWrap(true);
|
||||
}
|
||||
if (!I.hasNoUnsignedWrap() && WillNotOverflowUnsignedSub(Op0, Op1)) {
|
||||
Changed = true;
|
||||
I.setHasNoUnsignedWrap(true);
|
||||
}
|
||||
|
||||
return Changed ? &I : nullptr;
|
||||
}
|
||||
|
@ -506,6 +506,18 @@ define i4 @test42(i4 %x, i4 %y) {
|
||||
; CHECK-LABEL: @test42(
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i4 %y, 7
|
||||
; CHECK-NEXT: [[AND1:%.*]] = and i4 %x, 7
|
||||
; CHECK-NEXT: [[RET:%.*]] = sub nsw i4 %a, %b
|
||||
; CHECK-NEXT: [[RET:%.*]] = sub nsw i4 [[AND]], [[AND1]]
|
||||
; CHECK: ret i4 [[RET]]
|
||||
}
|
||||
|
||||
define i4 @test43(i4 %x, i4 %y) {
|
||||
%a = or i4 %x, -8
|
||||
%b = and i4 %y, 7
|
||||
%c = sub i4 %a, %b
|
||||
ret i4 %c
|
||||
; CHECK-LABEL: @test43(
|
||||
; CHECK-NEXT: [[OR:%.*]] = or i4 %x, -8
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i4 %y, 7
|
||||
; CHECK-NEXT: [[RET:%.*]] = sub nuw i4 [[OR]], [[AND]]
|
||||
; CHECK: ret i4 [[RET]]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user