Skip to content

Loop Unroll Miscompile #51102

@isanbard

Description

@isanbard
Bugzilla Link 51760
Resolution FIXED
Resolved on Sep 08, 2021 10:25
Version trunk
OS All
Blocks #50580
Attachments Reduced example, Original, unreduced, file., Unlzma function right before loop unrolling
CC @efriedma-quic,@fhahn,@LebedevRI,@nickdesaulniers,@nikic
Fixed by commit(s) 8d54c8a a98b397

Extended Description

The commit https://reviews.llvm.org/D104741 either introduced or exposed a potential loop unrolling bug. This comes up in the Linux decompress_unlzma() function. What seems to be happening is this subloop:

.buggy.while.body: %rc.sroa.23.25 = phi i8* [ undef, %.buggy.rc_normalize.exit ], [ %rc.sroa.23.21, %if.else112.i ] %rc.sroa.250.17 = phi i32 [ %shr.i540.i, %.buggy.rc_normalize.exit ], [ %rc.sroa.250.16.5, %if.else112.i ] %num_bits.1646.i = phi i32 [ %dec.i, %.buggy.rc_normalize.exit ], [ %sub113.i, %if.else112.i ] %dec.i = add nsw i32 %num_bits.1646.i, -1 %cmp.i.i525.i = icmp ult i32 %rc.sroa.250.17, 16777216 br i1 %cmp.i.i525.i, label %.buggy.if.then, label %.buggy.rc_normalize.exit .buggy.if.then: %cmp.not.i.i.i.i185 = icmp ult i8* %rc.sroa.23.25, %add.ptr.i br i1 %cmp.not.i.i.i.i185, label %.buggy.rc_do_normalize.exit, label %if.then.i.i.i.i536.i if.then.i.i.i.i536.i: ; preds = %.buggy.if.then unreachable .buggy.rc_do_normalize.exit: %shl.i.i.i.i194 = shl nuw i32 %rc.sroa.250.17, 8 br label %.buggy.rc_normalize.exit .buggy.rc_normalize.exit: %.buggy.wrong.phi.value = phi i32 [ %shl.i.i.i.i194, %.buggy.rc_do_normalize.exit ], [ %rc.sroa.250.17, %.buggy.while.body ] %shr.i540.i = lshr i32 %.buggy.wrong.phi.value, 1 %tobool114.not.i = icmp eq i32 %dec.i, 0 br i1 %tobool114.not.i, label %while.end.i204, label %.buggy.while.body, !llvm.loop !​2 

becomes this:

define void @​unlzma(i8* nocapture readnone %buf, i64 %in_len) local_unnamed_addr #​0 { entry: ... .buggy.if.then: tail call void @​llvm.assume(i1 %cmp.not.i.i.i.i185) %shl.i.i.i.i194 = shl nuw i32 %mul.i.i.i500.i.5, 8 br label %.buggy.rc_normalize.exit .buggy.rc_normalize.exit: %.buggy.wrong.phi.value = phi i32 [ %shl.i.i.i.i194, %.buggy.if.then ], [ %mul.i.i.i500.i.5, %if.else112.i ] %shr.i540.i = lshr i32 %.buggy.wrong.phi.value, 1 %shr643.i.mask = and i32 %sub.i522.i, -2 %tobool114.not.i = icmp eq i32 %shr643.i.mask, 12 br i1 %tobool114.not.i, label %while.body127.i, label %.buggy.while.body.1, !llvm.loop !​0 ... .buggy.while.body.1: ; preds = %.buggy.rc_normalize.exit %cmp.i.i525.i.1 = icmp ult i32 %.buggy.wrong.phi.value, 33554432 br i1 %cmp.i.i525.i.1, label %.buggy.if.then.1, label %.buggy.rc_normalize.exit.1 .buggy.if.then.1: ; preds = %.buggy.while.body.1 tail call void @​llvm.assume(i1 %cmp.not.i.i.i.i185) %shl.i.i.i.i194.1 = shl nuw i32 %shr.i540.i, 8 br label %.buggy.rc_normalize.exit.1 .buggy.rc_normalize.exit.1: ; preds = %.buggy.if.then.1, %.buggy.while.body.1 %.buggy.wrong.phi.value.1 = phi i32 [ %shl.i.i.i.i194.1, %.buggy.if.then.1 ], [ %shr.i540.i, %.buggy.while.body.1 ] %shr.i540.i.1 = lshr i32 %.buggy.wrong.phi.value.1, 1 br label %while.body127.i } 

In ".buggy.while.body.1", the compare instruction is using "%.buggy.wrong.phi.value". But I think it should be using "%.buggy.wrong.phi.value.1", from the ".buggy.rc_normalize.exit.1" block.

Original command:

$ clang-13 -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -disable-free -main-file-name reduced.ll -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=small -target-cpu x86-64 -target-feature -mmx -target-feature -sse -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=gdb -v -fcoverage-compilation-dir=/usr/local/google/home/morbo/prodkernel-gcc -nostdsysteminc -nobuiltininc -resource-dir /sandbox/morbo/llvm/llvm.opt.install/lib/clang/13.0.0 -O2 -Wno-unused-command-line-argument -Wno-address-of-packed-member -Wno-gnu -fdebug-compilation-dir=/usr/local/google/home/morbo/prodkernel-gcc -ferror-limit 19 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -o - -x ir reduced.ll 

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions