diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-03-01 16:18:35 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-03-01 16:18:35 -0800 |
commit | 0f63d368324c7ecd2c2d559981c680fecb3f1ad4 (patch) | |
tree | 5ce4a75bc10e31fd6722f0204c4e825a1e483b6b | |
parent | 30f2f338c415a51b59f02bc0e4c7ccfce947248d (diff) |
Only fold small constants into memory reference displacements.
This should more generally prevent negative values in index registers, but
still allow most uses of this address mode for structure references.
R=sehr@chromium.org
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3302
Review URL: https://codereview.chromium.org/12389054
-rw-r--r-- | lib/Target/X86/X86ISelDAGToDAG.cpp | 11 | ||||
-rw-r--r-- | test/NaCl/X86/nacl64-addrmodes.ll | 55 |
2 files changed, 62 insertions, 4 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index f4a9ca38d2..6bef55c2b0 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -608,11 +608,14 @@ bool X86DAGToDAGISel::FoldOffsetIntoAddress(uint64_t Offset, !isDispSafeForFrameIndex(Val)) return true; // LOCALMOD-BEGIN - // Do not allow negative displacements to be folded into memory operations. - // This results in trying to dereference a negative offset from RZP + // Do not fold large offsets into displacements. + // Various constant folding and address-mode selections can result in + // 32-bit operations (e.g. from GEP) getting folded into the displacement + // and often results in a negative value in the index register + // (see also LegalizeAddressModeForNaCl) else if (Subtarget->isTargetNaCl64() && - AM.BaseType == X86ISelAddressMode::RegBase && Val < 0 && - selectingMemOp) + AM.BaseType == X86ISelAddressMode::RegBase && + (Val > 65535 || Val < -65536) && selectingMemOp) return true; // LOCALMOD-END } diff --git a/test/NaCl/X86/nacl64-addrmodes.ll b/test/NaCl/X86/nacl64-addrmodes.ll index 772424b154..c4dc359bdb 100644 --- a/test/NaCl/X86/nacl64-addrmodes.ll +++ b/test/NaCl/X86/nacl64-addrmodes.ll @@ -12,3 +12,58 @@ define i16 @negativedisp(i32 %b) { %c = load i16* %arrayidx, align 2 ret i16 %c } + +@main.m2 = internal constant [1 x [1 x i32]] [[1 x i32] [i32 -60417067]], align 4 +define i1 @largeconst() nounwind { +; CHECK: largeconst +entry: + %retval = alloca i32, align 4 + %i = alloca i32, align 4 + %j = alloca i32, align 4 + %madat = alloca i32*, align 4 + store i32 0, i32* %retval + store i32 -270770481, i32* %i, align 4 + store i32 -1912319477, i32* %j, align 4 + %0 = load i32* %j, align 4 + %mul = mul nsw i32 %0, 233468377 + %add = add nsw i32 %mul, 689019309 + %1 = load i32* %i, align 4 + %mul1 = mul nsw i32 %1, 947877507 + %add2 = add nsw i32 %mul1, 1574375955 + %arrayidx = getelementptr inbounds [1 x i32]* getelementptr inbounds ([1 x [1 x i32]]* @main.m2, i32 0, i32 0), i32 %add2 + %2 = bitcast [1 x i32]* %arrayidx to i32* + %arrayidx3 = getelementptr inbounds i32* %2, i32 %add + store i32* %arrayidx3, i32** %madat, align 4 +; Ensure the large constant doesn't get folded into the load +; CHECK: nacl:(%r15 + %3 = load i32** %madat, align 4 + %4 = load i32* %3, align 4 + %conv = zext i32 %4 to i64 + %5 = load i32* %j, align 4 + %mul4 = mul nsw i32 %5, 233468377 + %add5 = add nsw i32 %mul4, 689019309 + %6 = load i32* %i, align 4 + %mul6 = mul nsw i32 %6, 947877507 + %add7 = add nsw i32 %mul6, 1574375955 + %arrayidx8 = getelementptr inbounds [1 x i32]* getelementptr inbounds ([1 x [1 x i32]]* @main.m2, i32 0, i32 0), i32 %add7 + %7 = bitcast [1 x i32]* %arrayidx8 to i32* + %arrayidx9 = getelementptr inbounds i32* %7, i32 %add5 +; Ensure the large constant doesn't get folded into the load +; CHECK: nacl:(%r15 + %8 = load i32* %arrayidx9, align 4 + %conv10 = zext i32 %8 to i64 + %mul11 = mul nsw i64 3795428823, %conv10 + %9 = load i32* %j, align 4 + %mul12 = mul nsw i32 %9, 233468377 + %add13 = add nsw i32 %mul12, 689019309 + %conv14 = sext i32 %add13 to i64 + %rem = srem i64 %conv14, 4294967295 + %xor = xor i64 2597389499, %rem + %mul15 = mul nsw i64 %xor, 3795428823 + %sub = sub nsw i64 %mul11, %mul15 + %add16 = add nsw i64 %sub, 3829710203 + %mul17 = mul nsw i64 %add16, 2824337475 + %add18 = add nsw i64 %mul17, 2376483023 + %cmp = icmp eq i64 %conv, %add18 + ret i1 %cmp +} |