Properly print 'P' modifier on inline asm memory operands.
authorAnton Korobeynikov <asl@math.spbu.ru>
Tue, 28 Apr 2009 21:49:33 +0000 (21:49 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Tue, 28 Apr 2009 21:49:33 +0000 (21:49 +0000)
This should fix PR3379 and PR4064.
Patch inspired by Edwin Török!

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

lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h
test/CodeGen/X86/2009-04-29-InlineAsmPMemoryModifier.ll [new file with mode: 0644]

index c2b053edd75f927e34945804d2d2bbcd0694012e..b3f4e15f022ef877dee6b6854d955124d42496a9 100644 (file)
@@ -570,12 +570,13 @@ void X86ATTAsmPrinter::printSSECC(const MachineInstr *MI, unsigned Op) {
 }
 
 void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
-                                            const char *Modifier){
+                                            const char *Modifier,
+                                            bool NotRIPRel) {
   MachineOperand BaseReg  = MI->getOperand(Op);
   MachineOperand IndexReg = MI->getOperand(Op+2);
   const MachineOperand &DispSpec = MI->getOperand(Op+3);
 
-  bool NotRIPRel = IndexReg.getReg() || BaseReg.getReg();
+  NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
   if (DispSpec.isGlobal() ||
       DispSpec.isCPI() ||
       DispSpec.isJTI() ||
@@ -615,14 +616,14 @@ void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
 }
 
 void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
-                                         const char *Modifier){
+                                         const char *Modifier, bool NotRIPRel){
   assert(isMem(MI, Op) && "Invalid memory reference!");
   MachineOperand Segment = MI->getOperand(Op+4);
   if (Segment.getReg()) {
       printOperand(MI, Op+4, Modifier);
       O << ':';
     }
-  printLeaMemReference(MI, Op, Modifier);
+  printLeaMemReference(MI, Op, Modifier, NotRIPRel);
 }
 
 void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
@@ -723,7 +724,7 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
       return false;
 
     case 'P': // Don't print @PLT, but do print as memory.
-      printOperand(MI, OpNo, "mem");
+      printOperand(MI, OpNo, "mem", /*NotRIPRel=*/true);
       return false;
     }
   }
@@ -749,7 +750,7 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
       // These only apply to registers, ignore on mem.
       break;
     case 'P': // Don't print @PLT, but do print as memory.
-      printOperand(MI, OpNo, "mem");
+      printMemReference(MI, OpNo, "mem", /*NotRIPRel=*/true);
       return false;
     }
   }
index 30630e97846a6d236f16d836807e7eebb0a7cd2b..65af91ac38808f5ef8ea7d09a7e3dc43c6536c9f 100644 (file)
@@ -112,9 +112,9 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
   void printMachineInstruction(const MachineInstr *MI);
   void printSSECC(const MachineInstr *MI, unsigned Op);
   void printMemReference(const MachineInstr *MI, unsigned Op,
-                         const char *Modifier=NULL);
+                         const char *Modifier=NULL, bool NotRIPRel = false);
   void printLeaMemReference(const MachineInstr *MI, unsigned Op,
-                            const char *Modifier=NULL);
+                            const char *Modifier=NULL, bool NotRIPRel = false);
   void printPICJumpTableSetLabel(unsigned uid,
                                  const MachineBasicBlock *MBB) const;
   void printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
diff --git a/test/CodeGen/X86/2009-04-29-InlineAsmPMemoryModifier.ll b/test/CodeGen/X86/2009-04-29-InlineAsmPMemoryModifier.ll
new file mode 100644 (file)
index 0000000..65cee9d
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep gs: | not grep rip
+; PR3379
+
+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-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+@per_cpu__cpu_number = external global i32              ; <i32*> [#uses=1]
+
+define void @pat_init() nounwind {
+entry:
+        %0 = call i32 asm "movl %gs:${1:P},$0", "=r,*m,~{dirflag},~{fpsr},~{flags}"(i32* @per_cpu__cpu_number) nounwind         ; <i32> [#uses=0]
+        unreachable
+}