[LLVMbugs] [Bug 12513] New: Loop unrolling breaks with indirect branches

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Apr 9 19:53:27 PDT 2012


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

             Bug #: 12513
           Summary: Loop unrolling breaks with indirect branches
           Product: libraries
           Version: trunk
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Loop Optimizer
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: Pidgeot18 at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Simple test case:
; ModuleID = 'blah.ll'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

declare void @subtract() nounwind uwtable

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
entry:
  %vals19 = alloca [5 x i32], align 16
  %x20 = alloca i32, align 4
  store i32 135, i32* %x20, align 4
  br label %for.body

for.body:                                         ; preds = %call2_termjoin,
%call3_termjoin
  %indvars.iv = phi i64 [ 0, %entry ], [ %joinphi15.in.in, %call2_termjoin ]
  %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8*
blockaddress(@main, %for.body_codeprime)) nounwind
  indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime]

for.body_code:                                    ; preds = %for.body
  call void @subtract()
  br label %call2_termjoin

call2_termjoin:                                   ; preds =
%for.body_codeprime, %for.body_code
  %joinphi15.in.in = add i64 %indvars.iv, 1
  %exitcond = icmp eq i64 %joinphi15.in.in, 5
  br i1 %exitcond, label %for.end, label %for.body

for.end:                                          ; preds = %call2_termjoin
  ret i32 0

for.body_codeprime:                               ; preds = %for.body
  call void @subtract_v2(i64 %indvars.iv)
  br label %call2_termjoin
}

declare coldcc i8* @funca(i8*, i8*) readonly

declare void @subtract_v2(i64) nounwind uwtable


Compile with -loop-unroll and -simplifycfg. Result:
; ModuleID = 'blah.ll'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

declare void @subtract() nounwind uwtable

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
entry:
  %vals19 = alloca [5 x i32], align 16
  %x20 = alloca i32, align 4
  store i32 135, i32* %x20, align 4
  %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8*
blockaddress(@main, %for.body_codeprime)) nounwind
  indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime]

for.body_code:                                    ; preds = %entry
  call void @subtract()
  unreachable

for.body_codeprime:                               ; preds = %entry
  call void @subtract_v2(i64 0)
  unreachable
}

declare coldcc i8* @funca(i8*, i8*) readonly

declare void @subtract_v2(i64) nounwind uwtable


Loop unrolling decides to unroll the loop, which clones the indirectbr, giving
each target of indirectbr different successors. Simplifycfgs notes that the
targets can never be reached by address, and helpfully deletes all successors
of indirectbr. As a result, the indirectbr has no possible successors, so it
marks it unreachable and proceeds to completely break code.

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