[PATCH] Fix assertion failure caused by InlineCost when ptrtoint int size is larger than the pointer size

Matt Arsenault Matthew.Arsenault at amd.com
Mon Jul 8 10:25:06 PDT 2013


Hi chandlerc,

When the int was larger than the pointer size, the saved constant
offset would be the wrong type at the uses, resulting in this failure.
    
In the added test case for example, the sub i64 ended up with
i32 operands, which would then fail on its use in the icmp.


http://llvm-reviews.chandlerc.com/D1114

Files:
  lib/Analysis/IPA/InlineCost.cpp
  test/Transforms/Inline/ptr-diff.ll

Index: lib/Analysis/IPA/InlineCost.cpp
===================================================================
--- lib/Analysis/IPA/InlineCost.cpp
+++ lib/Analysis/IPA/InlineCost.cpp
@@ -403,7 +403,7 @@
   // Track base/offset pairs when converted to a plain integer provided the
   // integer is large enough to represent the pointer.
   unsigned IntegerSize = I.getType()->getScalarSizeInBits();
-  if (TD && IntegerSize >= TD->getPointerSizeInBits()) {
+  if (TD && IntegerSize == TD->getPointerSizeInBits()) {
     std::pair<Value *, APInt> BaseAndOffset
       = ConstantOffsetPtrs.lookup(I.getOperand(0));
     if (BaseAndOffset.first)
@@ -440,7 +440,7 @@
   // modifications provided the integer is not too large.
   Value *Op = I.getOperand(0);
   unsigned IntegerSize = Op->getType()->getScalarSizeInBits();
-  if (TD && IntegerSize <= TD->getPointerSizeInBits()) {
+  if (TD && IntegerSize == TD->getPointerSizeInBits()) {
     std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.lookup(Op);
     if (BaseAndOffset.first)
       ConstantOffsetPtrs[&I] = BaseAndOffset;
Index: test/Transforms/Inline/ptr-diff.ll
===================================================================
--- test/Transforms/Inline/ptr-diff.ll
+++ test/Transforms/Inline/ptr-diff.ll
@@ -29,6 +29,36 @@
   ret i32 %t
 }
 
+; Make sure that assertion isn't hit when ptrtoint is used with an
+; integer size different from the pointer size
+define i32 @outer1_ptrtoint_larger() {
+; CHECK: @outer1_ptrtoint_larger
+; CHECK: ret i32
+
+  %ptr = alloca i32
+  %ptr1 = getelementptr inbounds i32* %ptr, i64 0
+  %ptr2 = getelementptr inbounds i32* %ptr, i64 42
+  %result = call i32 @inner1_ptrtoint_larger(i32* %ptr1, i32* %ptr2)
+  ret i32 %result
+}
+
+; Copy of inner1 that uses a ptrtoint to an integer that is larger
+; than the pointer size
+define i32 @inner1_ptrtoint_larger(i32* %begin, i32* %end) {
+  %begin.i = ptrtoint i32* %begin to i64
+  %end.i = ptrtoint i32* %end to i64
+  %distance = sub i64 %end.i, %begin.i
+  %icmp = icmp sle i64 %distance, 42
+  br i1 %icmp, label %then, label %else
+
+then:
+  ret i32 3
+
+else:
+  %t = load i32* %begin
+  ret i32 %t
+}
+
 define i32 @outer2(i32* %ptr) {
 ; Test that an inbounds GEP disables this -- it isn't safe in general as
 ; wrapping changes the behavior of lessthan and greaterthan comparisions.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1114.1.patch
Type: text/x-patch
Size: 2349 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130708/7d8dfdad/attachment.bin>


More information about the llvm-commits mailing list