[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