[llvm-commits] [llvm] r135084 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll

Eli Friedman eli.friedman at gmail.com
Wed Jul 13 14:29:53 PDT 2011


Author: efriedma
Date: Wed Jul 13 16:29:53 2011
New Revision: 135084

URL: http://llvm.org/viewvc/llvm-project?rev=135084&view=rev
Log:
Make sure we don't combine a large displacement and a frame index in the same addressing mode on x86-64.  It can overflow, leading to a crash/miscompile.

<rdar://problem/9763308>


Added:
    llvm/trunk/test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=135084&r1=135083&r2=135084&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Jul 13 16:29:53 2011
@@ -548,17 +548,33 @@
       EmitSpecialCodeForMain(MF->begin(), MF->getFrameInfo());
 }
 
+static bool isDispSafeForFrameIndex(int64_t Val) {
+  // On 64-bit platforms, we can run into an issue where a frame index
+  // includes a displacement that, when added to the explicit displacement,
+  // will overflow the displacement field. Assuming that the frame index
+  // displacement fits into a 31-bit integer  (which is only slightly more
+  // aggressive than the current fundamental assumption that it fits into
+  // a 32-bit integer), a 31-bit disp should always be safe.
+  return isInt<31>(Val);
+}
+
 bool X86DAGToDAGISel::FoldOffsetIntoAddress(uint64_t Offset,
                                             X86ISelAddressMode &AM) {
   int64_t Val = AM.Disp + Offset;
   CodeModel::Model M = TM.getCodeModel();
-  if (!Subtarget->is64Bit() ||
-      X86::isOffsetSuitableForCodeModel(Val, M,
-                                        AM.hasSymbolicDisplacement())) {
-    AM.Disp = Val;
-    return false;
+  if (Subtarget->is64Bit()) {
+    if (!X86::isOffsetSuitableForCodeModel(Val, M,
+                                           AM.hasSymbolicDisplacement()))
+      return true;
+    // In addition to the checks required for a register base, check that
+    // we do not try to use an unsafe Disp with a frame index.
+    if (AM.BaseType == X86ISelAddressMode::FrameIndexBase &&
+        !isDispSafeForFrameIndex(Val))
+      return true;
   }
-  return true;
+  AM.Disp = Val;
+  return false;
+
 }
 
 bool X86DAGToDAGISel::MatchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM){
@@ -751,8 +767,9 @@
     break;
 
   case ISD::FrameIndex:
-    if (AM.BaseType == X86ISelAddressMode::RegBase
-        && AM.Base_Reg.getNode() == 0) {
+    if (AM.BaseType == X86ISelAddressMode::RegBase &&
+        AM.Base_Reg.getNode() == 0 &&
+        (!Subtarget->is64Bit() || isDispSafeForFrameIndex(AM.Disp))) {
       AM.BaseType = X86ISelAddressMode::FrameIndexBase;
       AM.Base_FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
       return false;

Added: llvm/trunk/test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll?rev=135084&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2011-07-13-BadFrameIndexDisplacement.ll Wed Jul 13 16:29:53 2011
@@ -0,0 +1,20 @@
+; RUN: llc -march=x86-64 < %s -disable-fp-elim | FileCheck %s
+
+; This test is checking that we don't crash and we don't incorrectly fold
+; a large displacement and a frame index into a single lea.
+; <rdar://problem/9763308>
+
+declare void @bar([39 x i8]*)
+define i32 @f(i64 %a, i64 %b) nounwind readnone {
+entry:
+  %stack_main = alloca [39 x i8]
+  call void @bar([39 x i8]* %stack_main)
+  %tmp6 = add i64 %a, -2147483647
+  %.sum = add i64 %tmp6, %b
+  %tmp8 = getelementptr inbounds [39 x i8]* %stack_main, i64 0, i64 %.sum
+  %tmp9 = load i8* %tmp8, align 1
+  %tmp10 = sext i8 %tmp9 to i32
+  ret i32 %tmp10
+}
+; CHECK: f:
+; CHECK: movsbl	-2147483647





More information about the llvm-commits mailing list