<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>