[LLVMbugs] [Bug 2467] New: Invalid instcombine of inttoptr -> gep

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Tue Jun 17 00:13:30 PDT 2008


http://llvm.org/bugs/show_bug.cgi?id=2467

           Summary: Invalid instcombine of inttoptr -> gep
           Product: new-bugs
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: new bugs
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: sharparrow1 at yahoo.com
                CC: llvmbugs at cs.uiuc.edu


The current inttoptr ->gep optimization in InstCombiner::visitIntToPtr will
always optimize inttoptr(add (ptrtoint x), cst) to gep x, cst.  This is an
invalid transformation in general because unlike integer arithmetic, overflow
for a GEP is undefined.  Therefore, the transformation is only valid if the
resultant pointer is guaranteed to be valid.  (There are a few ways to make
this guarantee: one is if the resulting pointer is immediately loaded from,
another is to ensure x is an object of known size.)

Sample program that breaks when run through clang -emit-llvm-bc | opt
-std-compile-opts (it's a little complicated because it has to trigger both the
bad optimization and an undefined overflow optimization):

int* a(int* a, int i) {return
(int*)((unsigned)((int*)((unsigned)(a)+0x80000000))+0x80000000)+i;}
unsigned b(int* b, int i) {return a(b, i) == b+i;}
int main(int argc, char** argv) {if (!b(&argc, argc)) abort();}

Output of clang -emit-llvm-bc for this program run through mem2reg:
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i686-pc-linux-gnu"

define i32* @a(i32* %a, i32 %i) {
entry:
        %conv = ptrtoint i32* %a to i32
        %add = add i32 %conv, -2147483648
        %conv1 = inttoptr i32 %add to i32*
        %conv2 = ptrtoint i32* %conv1 to i32
        %add3 = add i32 %conv2, -2147483648
        %conv4 = inttoptr i32 %add3 to i32*
        %add.ptr = getelementptr i32* %conv4, i32 %i
        ret i32* %add.ptr
}

define i32 @b(i32* %b, i32 %i) {
entry:
        %call = call i32* @a( i32* %b, i32 %i )
        %add.ptr = getelementptr i32* %b, i32 %i
        %cmp = icmp eq i32* %call, %add.ptr
        %cmp.ext = zext i1 %cmp to i32
        ret i32 %cmp.ext
}

define i32 @main(i32 %argc, i8** %argv) {
entry:
        %argc.addr = alloca i32
        store i32 %argc, i32* %argc.addr
        %tmp = load i32* %argc.addr
        %call = call i32 @b( i32* %argc.addr, i32 %tmp )
        %tobool = icmp ne i32 %call, 0
        %lnot = xor i1 %tobool, true
        br i1 %lnot, label %ifthen, label %ifend

ifthen:         ; preds = %entry
        %call1 = call i32 (...)* @abort( )
        br label %ifend

ifend:          ; preds = %ifthen, %entry
        ret i32 undef
}

Resultant program after running this through opt -std-compile-opts:
; ModuleID = '<stdin>'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
target triple = "i686-pc-linux-gnu"

define i32* @a(i32* %a, i32 %i) nounwind  {
entry:
        %conv1.sum = add i32 %i, -1073741824
        %add.ptr = getelementptr i32* %a, i32 %conv1.sum
        ret i32* %add.ptr
}

define i32 @b(i32* %b, i32 %i) nounwind  {
entry:
        %conv1.sum.i = add i32 %i, -1073741824
        %cmp = icmp eq i32 %conv1.sum.i, %i
        %cmp.ext = zext i1 %cmp to i32
        ret i32 %cmp.ext
}

define i32 @main(i32 %argc, i8** %argv) {
entry:
        %conv1.sum.i.i = add i32 %argc, -1073741824
        %cmp.i = icmp eq i32 %conv1.sum.i.i, %argc
        br i1 %cmp.i, label %ifend, label %ifthen

ifthen:         ; preds = %entry
        %call1 = tail call i32 (...)* @abort( )
        ret i32 undef

ifend:          ; preds = %entry
        ret i32 undef
}

declare i32 @abort(...)

There's also another issue with the optimization: it doesn't make sure that the
ptrtoint doesn't lose information by casting to a narrower type.


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list