mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Add back commit r210029.
The code was actually correct. Sorry for the confusion. I have expanded the comment saying why the analysis is valid to avoid me misunderstaning it again in the future. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210052 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
376d5ef3c6
commit
27bd9b361b
@ -898,10 +898,20 @@ bool InstCombiner::WillNotOverflowSignedAdd(Value *LHS, Value *RHS) {
|
||||
// There are different heuristics we can use for this. Here are some simple
|
||||
// ones.
|
||||
|
||||
// Add has the property that adding any two 2's complement numbers can only
|
||||
// have one carry bit which can change a sign. As such, if LHS and RHS each
|
||||
// have at least two sign bits, we know that the addition of the two values
|
||||
// will sign extend fine.
|
||||
// If LHS and RHS each have at least two sign bits, the addition will look
|
||||
// like
|
||||
//
|
||||
// XX..... +
|
||||
// YY.....
|
||||
//
|
||||
// If the carry into the most significant position is 0, X and Y can't both
|
||||
// be 1 and therefore the carry out of the addition is also 0.
|
||||
//
|
||||
// If the carry into the most significant position is 1, X and Y can't both
|
||||
// be 0 and therefore the carry out of the addition is also 1.
|
||||
//
|
||||
// Since the carry into the most significant position is always equal to
|
||||
// the carry out of the addition, there is no signed overflow.
|
||||
if (ComputeNumSignBits(LHS) > 1 && ComputeNumSignBits(RHS) > 1)
|
||||
return true;
|
||||
|
||||
@ -1191,6 +1201,11 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
return BinaryOperator::CreateOr(A, B);
|
||||
}
|
||||
|
||||
if (!I.hasNoSignedWrap() && WillNotOverflowSignedAdd(LHS, RHS)) {
|
||||
Changed = true;
|
||||
I.setHasNoSignedWrap(true);
|
||||
}
|
||||
|
||||
return Changed ? &I : nullptr;
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ define zeroext i64 @test43(i8 zeroext %on_off) nounwind readonly {
|
||||
ret i64 %C ;; Should be (add (zext i8 -> i64), -1)
|
||||
; CHECK-LABEL: @test43(
|
||||
; CHECK-NEXT: %A = zext i8 %on_off to i64
|
||||
; CHECK-NEXT: %B = add i64 %A, -1
|
||||
; CHECK-NEXT: %B = add nsw i64 %A, -1
|
||||
; CHECK-NEXT: ret i64 %B
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ define i32 @test_simplify13(i32 %x) {
|
||||
; CHECK-LABEL: @test_simplify13(
|
||||
%ret = call i32 @ffs(i32 %x)
|
||||
; CHECK-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1
|
||||
; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add nsw i32 [[CTTZ]], 1
|
||||
; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
|
||||
; CHECK-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
|
||||
ret i32 %ret
|
||||
@ -114,7 +114,7 @@ define i32 @test_simplify14(i32 %x) {
|
||||
; CHECK-LINUX-LABEL: @test_simplify14(
|
||||
%ret = call i32 @ffsl(i32 %x)
|
||||
; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false)
|
||||
; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1
|
||||
; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nsw i32 [[CTTZ]], 1
|
||||
; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0
|
||||
; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0
|
||||
ret i32 %ret
|
||||
@ -125,7 +125,7 @@ define i32 @test_simplify15(i64 %x) {
|
||||
; CHECK-LINUX-LABEL: @test_simplify15(
|
||||
%ret = call i32 @ffsll(i64 %x)
|
||||
; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %x, i1 false)
|
||||
; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i64 [[CTTZ]], 1
|
||||
; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nsw i64 [[CTTZ]], 1
|
||||
; CHECK-LINUX-NEXT: [[TRUNC:%[a-z0-9]+]] = trunc i64 [[INC]] to i32
|
||||
; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i64 %x, 0
|
||||
; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[TRUNC]], i32 0
|
||||
|
@ -127,7 +127,7 @@ define i64 @test14(i64 %x, i32 %y) {
|
||||
; CHECK-LABEL: @test14(
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, %y
|
||||
; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ZEXT]], -1
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[ZEXT]], -1
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i64 [[ADD]], %x
|
||||
; CHECK-NEXT: ret i64 [[AND]]
|
||||
%shl = shl i32 1, %y
|
||||
|
@ -281,7 +281,7 @@ define i32 @test15i(i32 %X) {
|
||||
; CHECK-NEXT: %t1 = shl i32 %X, 8
|
||||
; CHECK-NEXT: %1 = and i32 %t1, 512
|
||||
; CHECK-NEXT: %2 = xor i32 %1, 512
|
||||
; CHECK-NEXT: %3 = add i32 %2, 577
|
||||
; CHECK-NEXT: %3 = add nsw i32 %2, 577
|
||||
; CHECK-NEXT: ret i32 %3
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ define i32 @test15j(i32 %X) {
|
||||
; CHECK-LABEL: @test15j(
|
||||
; CHECK-NEXT: %t1 = shl i32 %X, 8
|
||||
; CHECK-NEXT: %1 = and i32 %t1, 512
|
||||
; CHECK-NEXT: %2 = add i32 %1, 577
|
||||
; CHECK-NEXT: %2 = add nsw i32 %1, 577
|
||||
; CHECK-NEXT: ret i32 %2
|
||||
}
|
||||
|
||||
@ -521,7 +521,7 @@ define i32 @test35(i32 %x) {
|
||||
; CHECK-LABEL: @test35(
|
||||
; CHECK: ashr i32 %x, 31
|
||||
; CHECK: and i32 {{.*}}, 40
|
||||
; CHECK: add i32 {{.*}}, 60
|
||||
; CHECK: add nsw i32 {{.*}}, 60
|
||||
; CHECK: ret
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ define i32 @test36(i32 %x) {
|
||||
; CHECK-LABEL: @test36(
|
||||
; CHECK: ashr i32 %x, 31
|
||||
; CHECK: and i32 {{.*}}, -40
|
||||
; CHECK: add i32 {{.*}}, 100
|
||||
; CHECK: add nsw i32 {{.*}}, 100
|
||||
; CHECK: ret
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ define i32 @test13(i32 %x) nounwind {
|
||||
; CHECK-LABEL: @test13(
|
||||
; CHECK-NEXT: %and = lshr i32 %x, 3
|
||||
; CHECK-NEXT: %1 = and i32 %and, 1
|
||||
; CHECK-NEXT: %sext = add i32 %1, -1
|
||||
; CHECK-NEXT: %sext = add nsw i32 %1, -1
|
||||
; CHECK-NEXT: ret i32 %sext
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ define i32 @test14(i16 %x) nounwind {
|
||||
; CHECK-LABEL: @test14(
|
||||
; CHECK-NEXT: %and = lshr i16 %x, 4
|
||||
; CHECK-NEXT: %1 = and i16 %and, 1
|
||||
; CHECK-NEXT: %sext = add i16 %1, -1
|
||||
; CHECK-NEXT: %sext = add nsw i16 %1, -1
|
||||
; CHECK-NEXT: %ext = sext i16 %sext to i32
|
||||
; CHECK-NEXT: ret i32 %ext
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ entry:
|
||||
; CHECK-LABEL: @a(
|
||||
; CHECK: [[TMP1:%.*]] = sext i1 %y to i32
|
||||
; CHECK: [[TMP2:%.*]] = select i1 %x, i32 2, i32 1
|
||||
; CHECK-NEXT: add i32 [[TMP2]], [[TMP1]]
|
||||
; CHECK-NEXT: add nsw i32 [[TMP2]], [[TMP1]]
|
||||
%conv = zext i1 %x to i32
|
||||
%conv3 = zext i1 %y to i32
|
||||
%conv3.neg = sub i32 0, %conv3
|
||||
|
Loading…
Reference in New Issue
Block a user