LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 52276 - wrong code at -O1, -Os and -O2 (but not -O3) on x86_64-linux-gnu (generated code hangs)
Summary: wrong code at -O1, -Os and -O2 (but not -O3) on x86_64-linux-gnu (generated c...
Status: RESOLVED FIXED
Alias: None
Product: new-bugs
Classification: Unclassified
Component: new bugs (show other bugs)
Version: unspecified
Hardware: PC All
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-10-23 13:42 PDT by Zhendong Su
Modified: 2021-10-25 09:28 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zhendong Su 2021-10-23 13:42:30 PDT
This appears to be a recent regression.

[679] % clangtk -v
clang version 14.0.0 (https://github.com/llvm/llvm-project.git 2410fb4616b2c08bbaddd44e6c11da8285fbd1d3)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /local/suz-local/opfuzz/bin
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
[680] % 
[680] % clangtk -O0 small.c; ./a.out
[681] % 
[681] % clangtk -O1 small.c
[682] % timeout -s 9 10 ./a.out
Killed
[683] % 
[683] % cat small.c
int a, b;
int main() {
  while ((a > 0) < ~a)
    b++;
  return 0;
}
Comment 1 Sanjay Patel 2021-10-25 06:25:32 PDT
cc'ing @reames

This was caused/exposed by:
https://reviews.llvm.org/rG412eb07edd4e83afeb1e727e91213e2cbd771f29
https://reviews.llvm.org/D111836

define i32 @PR52276(i32 %a, i32* %p) {
entry:
  %cmp = icmp sgt i32 %a, 0
  %conv = zext i1 %cmp to i32
  %neg = xor i32 %a, -1
  %cmp1 = icmp slt i32 %conv, %neg
  br i1 %cmp1, label %ph, label %exit

ph:
  %b = load i32, i32* %p, align 4
  br label %loop

loop:
  %inc1 = phi i32 [ %b, %ph ], [ %inc, %loop ]
  %inc = add nsw i32 %inc1, 1
  br i1 %cmp1, label %loop, label %crit_edge, !llvm.loop !0

crit_edge:
  %inc2 = phi i32 [ %inc, %loop ]
  store i32 %inc2, i32* %p, align 4
  br label %exit

exit:
  ret i32 0
}

!0 = distinct !{!0, !1}
!1 = !{!"llvm.loop.mustprogress"}
Comment 2 listmail 2021-10-25 09:10:43 PDT
Agreed, definitely a regression from my patch.  I'd missed a hasOneUse check somewhere in the process of splitting and rebasing this.  Will have a fix landed shortly, sorry for the breakage.  

p.s. The bug is actually introduced before the patch fingered.  That's simply the first one which exposes this particular use case.
Comment 3 listmail 2021-10-25 09:28:27 PDT
Should be fixed by:

commit f82cf6187fbe9584ba0a8d9bf4d703498df249e6 (HEAD -> main, origin/main)
Author: Philip Reames <listmail@philipreames.com>
Date:   Mon Oct 25 09:25:00 2021 -0700

    [indvars] Fix pr52276 (missing one use check)
    
    The recently added logic to canonicalize exit conditions to unsigned relies on facts which hold about the use (i.e. exit test).  Applying this blindly to the icmp is not legal, as there may be another use which never reaches the exit.  Restrict ourselves to case where we have a single use.

Please reopen if needed.  I confirmed the reduced test case was fixed, but not the original C example.