mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +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:
		| @@ -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 | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user