Fix some fast-isel problems selecting global variable addressing in
authorChris Lattner <sabre@nondot.org>
Wed, 1 Jul 2009 03:27:19 +0000 (03:27 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 1 Jul 2009 03:27:19 +0000 (03:27 +0000)
pic mode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74582 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86InstrBuilder.h
test/CodeGen/X86/fast-isel-gv.ll [new file with mode: 0644]

index 8a21b35c134fe97523483efeb55dba435053f4f9..ea29f73a066a090861b09aeee7b1db3f0dbe2b92 100644 (file)
@@ -457,20 +457,30 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
         AM.GV = 0;
         return true;
       }
-      // Issue load from stub if necessary.
+      
+      // Issue load from stub.
       unsigned Opc = 0;
       const TargetRegisterClass *RC = NULL;
+      X86AddressMode StubAM;
+      StubAM.Base.Reg = AM.Base.Reg;
+      StubAM.GV = AM.GV;
+      
       if (TLI.getPointerTy() == MVT::i32) {
         Opc = X86::MOV32rm;
         RC  = X86::GR32RegisterClass;
+        
+        if (Subtarget->isPICStyleGOT() &&
+            TM.getRelocationModel() == Reloc::PIC_)
+          StubAM.GVOpFlags = X86II::MO_GOT;
+        
       } else {
         Opc = X86::MOV64rm;
         RC  = X86::GR64RegisterClass;
+        
+        if (TM.getRelocationModel() != Reloc::Static)
+          StubAM.GVOpFlags = X86II::MO_GOTPCREL;
       }
 
-      X86AddressMode StubAM;
-      StubAM.Base.Reg = AM.Base.Reg;
-      StubAM.GV = AM.GV;
       unsigned ResultReg = createResultReg(RC);
       addFullAddress(BuildMI(MBB, DL, TII.get(Opc), ResultReg), StubAM);
 
index b50dd65a2997dff435b505442d312062e8d668fb..6359542819f468447405203047e3bb43b6059627 100644 (file)
@@ -49,8 +49,10 @@ struct X86AddressMode {
   unsigned IndexReg;
   unsigned Disp;
   GlobalValue *GV;
+  unsigned GVOpFlags;
 
-  X86AddressMode() : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0) {
+  X86AddressMode()
+    : BaseType(RegBase), Scale(1), IndexReg(0), Disp(0), GV(0), GVOpFlags(0) {
     Base.Reg = 0;
   }
 };
@@ -113,7 +115,7 @@ inline const MachineInstrBuilder &addLeaAddress(const MachineInstrBuilder &MIB,
     assert (0);
   MIB.addImm(AM.Scale).addReg(AM.IndexReg);
   if (AM.GV)
-    return MIB.addGlobalAddress(AM.GV, AM.Disp);
+    return MIB.addGlobalAddress(AM.GV, AM.Disp, AM.GVOpFlags);
   else
     return MIB.addImm(AM.Disp);
 }
diff --git a/test/CodeGen/X86/fast-isel-gv.ll b/test/CodeGen/X86/fast-isel-gv.ll
new file mode 100644 (file)
index 0000000..7a4b94d
--- /dev/null
@@ -0,0 +1,24 @@
+; RUN: llvm-as < %s | llc -fast-isel | grep {_kill@GOTPCREL}
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+@f = global i8 (...)* @kill            ; <i8 (...)**> [#uses=1]
+
+declare signext i8 @kill(...)
+
+define i32 @main() nounwind ssp {
+entry:
+       %retval = alloca i32            ; <i32*> [#uses=2]
+       %0 = alloca i32         ; <i32*> [#uses=2]
+       %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+       %1 = load i8 (...)** @f, align 8                ; <i8 (...)*> [#uses=1]
+       %2 = icmp ne i8 (...)* %1, @kill                ; <i1> [#uses=1]
+       %3 = zext i1 %2 to i32          ; <i32> [#uses=1]
+       store i32 %3, i32* %0, align 4
+       %4 = load i32* %0, align 4              ; <i32> [#uses=1]
+       store i32 %4, i32* %retval, align 4
+       br label %return
+
+return:                ; preds = %entry
+       %retval1 = load i32* %retval            ; <i32> [#uses=1]
+       ret i32 %retval1
+}