<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Different initialization code in 32b and 64b impact optimiztions"
href="http://llvm.org/bugs/show_bug.cgi?id=20192">20192</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Different initialization code in 32b and 64b impact optimiztions
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>MacOS X
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C++
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>ghoflehner@apple.com
</td>
</tr>
<tr>
<th>CC</th>
<td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>* SUMMARY
For function with block address the 32b and 64b initialization code is
different. The impacts downstream optimizations.
* NOTE:
Filed for clang to understand why initialization is different to start the
analysis process.
* STEPS TO REPRODUCE
Check 32b and 64b mode IR:
clang -m32 -O2 tools/clang/test/CodeGen/indirect-goto.c -mllvm
-print-before-all
vs.
clang -m32 -O2 tools/clang/test/CodeGen/indirect-goto.c -mllvm
-print-before-all
Version: any recent clang-600 or trunk should reproduce the issue.
* RESULTS
In 32b mode block hasAddressTaken bit has a referent count of 1. This prevents
optimizations like jump threading, inlining and others that check for the flag.
In 64b mode the "explicit" initialization code results in a zero reference
count and the bit is not set.
* REGRESSION
This issue was discovered after fix rdar://17245966
* NOTES
32b IR for function foo (similar for foo2) in the test case:
*** IR Dump Before Module Verifier ***
; Function Attrs: nounwind ssp uwtable
define internal i32 @foo(i32 %i) #0 {
entry:
%i.addr = alloca i32, align 4
%addrs = alloca [5 x i8*], align 4
%res = alloca i32, align 4
store i32 %i, i32* %i.addr, align 4, !tbaa !1
%0 = bitcast [5 x i8*]* %addrs to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* bitcast ([5 x i8*]*
@foo.addrs to i8*), i32 20, i32 4, i1 false)
store i32 1, i32* %res, align 4, !tbaa !1
%1 = load i32* %i.addr, align 4, !tbaa !1
%arrayidx = getelementptr inbounds [5 x i8*]* %addrs, i32 0, i32 %1
%2 = load i8** %arrayidx, align 4, !tbaa !5
br label %indirectgoto
L5: ; preds = %indirectgoto
%3 = load i32* %res, align 4, !tbaa !1
%mul = mul nsw i32 %3, 11
store i32 %mul, i32* %res, align 4, !tbaa !1
br label %L4
L4: ; preds = %L5, %indirectgoto
%4 = load i32* %res, align 4, !tbaa !1
%mul1 = mul nsw i32 %4, 7
store i32 %mul1, i32* %res, align 4, !tbaa !1
br label %L3
L3: ; preds = %L4, %indirectgoto
%5 = load i32* %res, align 4, !tbaa !1
%mul2 = mul nsw i32 %5, 5
store i32 %mul2, i32* %res, align 4, !tbaa !1
br label %L2
L2: ; preds = %L3, %indirectgoto
%6 = load i32* %res, align 4, !tbaa !1
%mul3 = mul nsw i32 %6, 3
store i32 %mul3, i32* %res, align 4, !tbaa !1
br label %L1
L1: ; preds = %L2, %indirectgoto
%7 = load i32* %res, align 4, !tbaa !1
%mul4 = mul nsw i32 %7, 2
store i32 %mul4, i32* %res, align 4, !tbaa !1
%8 = load i32* %res, align 4, !tbaa !1
ret i32 %8
indirectgoto: ; preds = %entry
%indirect.goto.dest = phi i8* [ %2, %entry ]
indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3, label
%L4, label %L5]
IR 64b:
*** IR Dump Before Module Verifier ***
; Function Attrs: nounwind ssp uwtable
define internal i32 @foo(i32 %i) #0 {
entry:
%i.addr = alloca i32, align 4
%addrs = alloca [5 x i8*], align 16
%res = alloca i32, align 4
%cleanup.dest.slot = alloca i32
store i32 %i, i32* %i.addr, align 4, !tbaa !1
%0 = bitcast [5 x i8*]* %addrs to i8*
call void @llvm.lifetime.start(i64 40, i8* %0) #1
%1 = bitcast [5 x i8*]* %addrs to i8*
call void @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 40, i32 16, i1 false)
%2 = bitcast i8* %1 to [5 x i8*]*
%3 = getelementptr [5 x i8*]* %2, i32 0, i32 0
store i8* blockaddress(@foo, %L1), i8** %3
%4 = getelementptr [5 x i8*]* %2, i32 0, i32 1
store i8* blockaddress(@foo, %L2), i8** %4
%5 = getelementptr [5 x i8*]* %2, i32 0, i32 2
store i8* blockaddress(@foo, %L3), i8** %5
%6 = getelementptr [5 x i8*]* %2, i32 0, i32 3
store i8* blockaddress(@foo, %L4), i8** %6
%7 = getelementptr [5 x i8*]* %2, i32 0, i32 4
store i8* blockaddress(@foo, %L5), i8** %7
store i32 1, i32* %res, align 4, !tbaa !1
%8 = load i32* %i.addr, align 4, !tbaa !1
%idxprom = zext i32 %8 to i64
%arrayidx = getelementptr inbounds [5 x i8*]* %addrs, i32 0, i64 %idxprom
%9 = load i8** %arrayidx, align 8, !tbaa !5
br label %indirectgoto
L5: ; preds = %indirectgoto
%10 = load i32* %res, align 4, !tbaa !1
%mul = mul nsw i32 %10, 11
store i32 %mul, i32* %res, align 4, !tbaa !1
br label %L4
L4: ; preds = %L5, %indirectgoto
%11 = load i32* %res, align 4, !tbaa !1
%mul1 = mul nsw i32 %11, 7
store i32 %mul1, i32* %res, align 4, !tbaa !1
br label %L3
L3: ; preds = %L4, %indirectgoto
%12 = load i32* %res, align 4, !tbaa !1
%mul2 = mul nsw i32 %12, 5
store i32 %mul2, i32* %res, align 4, !tbaa !1
br label %L2
L2: ; preds = %L3, %indirectgoto
%13 = load i32* %res, align 4, !tbaa !1
%mul3 = mul nsw i32 %13, 3
store i32 %mul3, i32* %res, align 4, !tbaa !1
br label %L1
L1: ; preds = %L2, %indirectgoto
%14 = load i32* %res, align 4, !tbaa !1
%mul4 = mul nsw i32 %14, 2
store i32 %mul4, i32* %res, align 4, !tbaa !1
%15 = load i32* %res, align 4, !tbaa !1
store i32 1, i32* %cleanup.dest.slot
%16 = bitcast [5 x i8*]* %addrs to i8*
call void @llvm.lifetime.end(i64 40, i8* %16) #1
ret i32 %15
indirectgoto: ; preds = %entry
%indirect.goto.dest = phi i8* [ %9, %entry ]
indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3, label
%L4, label %L5]
This is also filed rdar://17523868</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>