[AsmPrinter] Treat a narrowing PtrToInt like Trunc
authorShoaib Meenai <smeenai@fb.com>
Thu, 23 May 2019 16:29:09 +0000 (16:29 +0000)
committerShoaib Meenai <smeenai@fb.com>
Thu, 23 May 2019 16:29:09 +0000 (16:29 +0000)
When printing assembly for PtrToInt, AsmPrinter::lowerConstant
incorrectly assumed that if PtrToInt was not converting to an
int with exactly the same number of bits, it must be widening
to a larger int. But this isn't necessarily true; PtrToInt can
also shrink the size, which is useful when you want to produce
a known 32-bit pointer on a 64-bit platform (on x86_64 ELF
this yields a R_X86_64_32 relocation).

The old behavior of falling through to the widening case for a
narrowing PtrToInt yields bogus assembly code like this, which
fails to assemble because the no-op bit and it accidentally
creates is not a valid relocation:

```
        .long   a&-1
```

The fix is to treat a narrowing PtrToInt exactly the same as
it already treats Trunc: just emit the expression and let
the assembler deal with truncating it in the appropriate way.

Patch by Mat Hostetter <mjh@fb.com>.

Differential Revision: https://reviews.llvm.org/D61325

llvm-svn: 361508

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/test/CodeGen/X86/ptrtoint-narrow.ll [new file with mode: 0644]

index b57eac3..bf7776b 100644 (file)
@@ -2231,7 +2231,10 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
 
     // We can emit the pointer value into this slot if the slot is an
     // integer slot equal to the size of the pointer.
-    if (DL.getTypeAllocSize(Ty) == DL.getTypeAllocSize(Op->getType()))
+    //
+    // If the pointer is larger than the resultant integer, then
+    // as with Trunc just depend on the assembler to truncate it.
+    if (DL.getTypeAllocSize(Ty) <= DL.getTypeAllocSize(Op->getType()))
       return OpExpr;
 
     // Otherwise the pointer is smaller than the resultant integer, mask off
diff --git a/llvm/test/CodeGen/X86/ptrtoint-narrow.ll b/llvm/test/CodeGen/X86/ptrtoint-narrow.ll
new file mode 100644 (file)
index 0000000..c34e7b1
--- /dev/null
@@ -0,0 +1,6 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+@ptr = external global i8, align 1
+@ref = constant i32 ptrtoint (i8* @ptr to i32), align 4
+
+; CHECK: .long  ptr{{$}}