[PATCH] D61325: Treat a narrowing PtrToInt like Trunc when generating asm

Mat Hostetter via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 10:43:19 PDT 2019


mjhostet created this revision.
mjhostet added a reviewer: grosbach.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D61325

Files:
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/test/CodeGen/X86/ptrtoint-narrow.ll


Index: llvm/test/CodeGen/X86/ptrtoint-narrow.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/ptrtoint-narrow.ll
@@ -0,0 +1,5 @@
+; RUN: llc < %s -mtriple=x86_64-- -filetype=obj
+
+%struct.MyStruct = type { i32 }
+ at ptr = external global i8, align 1
+ at ref = global %struct.MyStruct { i32 trunc (i64 ptrtoint (i8* @ptr to i64) to i32) }, align 8
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -2232,7 +2232,10 @@
 
     // 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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61325.197374.patch
Type: text/x-patch
Size: 1156 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190430/f20e9a16/attachment.bin>


More information about the llvm-commits mailing list