[llvm-bugs] [Bug 39695] New: mis-optimization in LoopSink

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Nov 16 13:05:40 PST 2018


https://bugs.llvm.org/show_bug.cgi?id=39695

            Bug ID: 39695
           Summary: mis-optimization in LoopSink
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: carrot at google.com
                CC: llvm-bugs at lists.llvm.org

Optimize following code with

opt -S -loop-sink test1.ll


define i32 @foo(i32 %n, i8** %pp) !prof !0 {
entry:
  %ptr = load i8*, i8** %pp, align 8          ; Should not be sinkied
  store i8* null, i8** %pp, align 8           ; because of this store
  br label %for.cond

for.cond:                                         ; preds = %for.body, %entry
  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %cmp = icmp ult i32 %i.0, %n
  br i1 %cmp, label %for.body, label %for.end, !prof !1

for.body:                                         ; preds = %for.cond
  %0 = sext i32 %i.0 to i64
  %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %0
  %1 = load i8, i8* %arrayidx, align 1
  %or19 = call i8 @llvm.bitreverse.i8(i8 %1)
  %v = sext i8 %or19 to i32
  %inc = add i32 %i.0, %v
  br label %for.cond

for.end:                                          ; preds = %for.cond
  ret i32 %i.0
}

declare i8 @llvm.bitreverse.i8(i8) #0
attributes #0 = { nounwind readnone speculatable }

!0 = !{!"function_entry_count", i64 1}
!1 = !{!"branch_weights", i32 1, i32 2000}


I got

define i32 @foo(i32 %n, i8** %pp) !prof !0 {
entry:
  store i8* null, i8** %pp, align 8
  br label %for.cond

for.cond:                                         ; preds = %for.body, %entry
  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %cmp = icmp ult i32 %i.0, %n
  br i1 %cmp, label %for.body, label %for.end, !prof !1

for.body:                                         ; preds = %for.cond
  %ptr = load i8*, i8** %pp, align 8              ; wrongly sinked
  %0 = sext i32 %i.0 to i64
  %arrayidx = getelementptr inbounds i8, i8* %ptr, i64 %0
  %1 = load i8, i8* %arrayidx, align 1             ;  seg fault!
  %or19 = call i8 @llvm.bitreverse.i8(i8 %1)
  %v = sext i8 %or19 to i32
  %inc = add i32 %i.0, %v
  br label %for.cond

for.end:                                          ; preds = %for.cond
  %i.0.lcssa = phi i32 [ %i.0, %for.cond ]
  ret i32 %i.0.lcssa
}

In entry block load is followed by a store to the same address. After loop
sink, the load is moved into the loop, the stored value (null) instead of the
original value will be used.

The problem is when LoopSink calls canSinkOrHoistInst to check if an
instruction can be sunk into the loop, it only checks if loop body over writes
the memory, but it is not enough as demonstrated by this test case, all
instructions after sink candidate in loop preheader should also be checked.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20181116/6ff8639e/attachment.html>


More information about the llvm-bugs mailing list