aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-03-01 16:18:35 -0800
committerDerek Schuff <dschuff@chromium.org>2013-03-01 16:18:35 -0800
commit0f63d368324c7ecd2c2d559981c680fecb3f1ad4 (patch)
tree5ce4a75bc10e31fd6722f0204c4e825a1e483b6b
parent30f2f338c415a51b59f02bc0e4c7ccfce947248d (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.cpp11
-rw-r--r--test/NaCl/X86/nacl64-addrmodes.ll55
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
+}