mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-02 17:58:26 +00:00
[DAGCombine] Fix demanded bits computation for exact shifts.
Fixes a miscompilation of MultiSource/Benchmarks/MallocBench/gs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240796 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd39f3c6cb
commit
23a207d839
@ -700,6 +700,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
if (ShAmt >= BitWidth)
|
||||
break;
|
||||
|
||||
APInt InDemandedMask = (NewMask << ShAmt);
|
||||
|
||||
// If the shift is exact, then it does demand the low bits (and knows that
|
||||
// they are zero).
|
||||
if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
|
||||
InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
|
||||
|
||||
// If this is ((X << C1) >>u ShAmt), see if we can simplify this into a
|
||||
// single shift. We can do this if the top bits (which are shifted out)
|
||||
// are never demanded.
|
||||
@ -722,7 +729,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
}
|
||||
|
||||
// Compute the new bits that are at the top now.
|
||||
if (SimplifyDemandedBits(InOp, (NewMask << ShAmt),
|
||||
if (SimplifyDemandedBits(InOp, InDemandedMask,
|
||||
KnownZero, KnownOne, TLO, Depth+1))
|
||||
return true;
|
||||
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
|
||||
@ -753,6 +760,11 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
|
||||
|
||||
APInt InDemandedMask = (NewMask << ShAmt);
|
||||
|
||||
// If the shift is exact, then it does demand the low bits (and knows that
|
||||
// they are zero).
|
||||
if (cast<BinaryWithFlagsSDNode>(Op)->Flags.hasExact())
|
||||
InDemandedMask |= APInt::getLowBitsSet(BitWidth, ShAmt);
|
||||
|
||||
// If any of the demanded bits are produced by the sign extension, we also
|
||||
// demand the input sign bit.
|
||||
APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
|
||||
|
@ -193,3 +193,22 @@ define i32 @test11(i32 %b) {
|
||||
; X32: movl $-2, %[[REG:.*]]
|
||||
; X32: roll %{{.*}}, %[[REG]]
|
||||
}
|
||||
|
||||
%struct.ref_s = type { %union.v, i16, i16 }
|
||||
%union.v = type { i64 }
|
||||
|
||||
define %struct.ref_s* @test12(%struct.ref_s* %op, i64 %osbot, i64 %intval) {
|
||||
%neg = shl i64 %intval, 32
|
||||
%sext = xor i64 %neg, -4294967296
|
||||
%idx.ext = ashr exact i64 %sext, 32
|
||||
%add.ptr = getelementptr inbounds %struct.ref_s, %struct.ref_s* %op, i64 %idx.ext
|
||||
ret %struct.ref_s* %add.ptr
|
||||
; X64-LABEL: test12:
|
||||
; X64: shlq $32, %[[REG:.*]]
|
||||
; X64-NOT: not
|
||||
; X64: sarq $28, %[[REG]]
|
||||
; X32-LABEL: test12:
|
||||
; X32: leal
|
||||
; X32-NOT: not
|
||||
; X32: shll $2, %eax
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user