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 51531 - wrong code at -O3 on x86_64-linux-gnu
Summary: wrong code at -O3 on x86_64-linux-gnu
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: LLVM Codegen (show other bugs)
Version: trunk
Hardware: PC All
: P enhancement
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-08-18 22:22 PDT by Qirun Zhang
Modified: 2021-08-20 11:41 PDT (History)
6 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 Qirun Zhang 2021-08-18 22:22:24 PDT
It appears to be a recent regression.

$ clang-trunk -v
clang version 14.0.0 (https://github.com/llvm/llvm-project.git 4f5ba46e162eec32a9f9e2a725e6422281913043)

$ clang-trunk abc.c ; ./a.out
0

$ clang-trunk -O2 abc.c ; ./a.out



$ cat abc.c
int a, c, d;
char e, f;
char(g)(char h, char i) { return i == 0 || h == -128 && i == 1 ? h : h % i; }
char k() {
  int j;
  d = 3;
  for (;; d--)
    for (;;) {
      short b = g(d, e | d);
      j = !b + 1;
      f = (1 == b) * j;
      c = b;
      if (d)
        break;
      return 1;
    }
}
int main() {
  k();
  printf("%X\n", a);
}
Comment 1 Qirun Zhang 2021-08-18 22:23:46 PDT
My bisection points to 

commit 9934a5b2ed5aa6e6bbb2e55c3cd98839722c226e
Author: Jun Ma <JunMa@linux.alibaba.com>
Date:   Thu Jul 15 18:37:40 2021 +0800

    [CVP] processSwitch: Remove default case when switch cover all possible values.

    Differential Revision: https://reviews.llvm.org/D106056

 llvm/include/llvm/Transforms/Utils/Local.h         |  5 +++
 .../Scalar/CorrelatedValuePropagation.cpp          | 27 ++++++++++++++-
 llvm/lib/Transforms/Utils/Local.cpp                | 24 ++++++++++++++
 llvm/lib/Transforms/Utils/SimplifyCFG.cpp          | 23 -------------
 .../Transforms/CorrelatedValuePropagation/basic.ll | 38 +++++++++++++++++++++-
 5 files changed, 92 insertions(+), 25 deletions(-)
Comment 2 JunMa 2021-08-19 02:29:16 PDT
https://godbolt.org/z/qn4Enffoc, I can not reproduce. Also this patch only handle switchinst, this testcase has no swtichinst.
Comment 3 Sanjay Patel 2021-08-19 05:03:37 PDT
(In reply to JunMa from comment #2)
> https://godbolt.org/z/qn4Enffoc, I can not reproduce. Also this patch only
> handle switchinst, this testcase has no swtichinst.

The C source is irrelevant; the IR has a switch, and https://reviews.llvm.org/D106056 appears to be at fault or exposing a bug somewhere else.

Here's a reduced test for "opt -correlated-propagation" (it can probably be reduced further):

define i8 @src(i8 %t0) {
g.exit:
  %conv3 = or i8 %t0, 3
  %rem.rhs.trunc.i = sext i8 %conv3 to i16
  %rem16.i = srem i16 3, %rem.rhs.trunc.i
  %rem.sext.i = trunc i16 %rem16.i to i8
  switch i8 %rem.sext.i, label %g.exit.1 [
    i8 0, label %g.exit.1
    i8 1, label %g.exit.1
  ]

g.exit.1:; preds = %g.exit, %g.exit, %g.exit
  %conv3.1 = or i8 %t0, 2
  %rem.rhs.trunc.i.1 = sext i8 %conv3.1 to i16
  %rem16.i.1 = srem i16 2, %rem.rhs.trunc.i.1
  %rem.sext.i.1 = trunc i16 %rem16.i.1 to i8
  switch i8 %rem.sext.i.1, label %g.exit.2 [
    i8 0, label %g.exit.2
    i8 1, label %g.exit.2
  ]

g.exit.2:; preds = %g.exit.1, %g.exit.1, %g.exit.1
  %conv3.2 = or i8 %t0, 1
  %rem.rhs.trunc.i.2 = sext i8 %conv3.2 to i16
  %rem16.i.2 = srem i16 1, %rem.rhs.trunc.i.2
  %rem.sext.i.2 = trunc i16 %rem16.i.2 to i8
  switch i8 %rem.sext.i.2, label %.thread.2 [
    i8 0, label %.thread.2
    i8 1, label %.thread.2
  ]

.thread.2:; preds = %g.exit.2, %g.exit.2, %g.exit.2
  %cmp.i.3 = icmp eq i8 %t0, 0
  br i1 %cmp.i.3, label %.thread.3, label %.thread.3

.thread.3:; preds = %.thread.2, %.thread.2
  ret i8 0
}
Comment 4 Sanjay Patel 2021-08-19 05:04:50 PDT
Alive2 appears to confirm that the switch transform is at fault:
https://alive2.llvm.org/ce/z/artAVo
Comment 5 Sanjay Patel 2021-08-19 05:52:15 PDT
I reverted the original patch, so we are not blocking anyone while investigating.

Here's a further reduction that seems to make the problem obvious - if the default block is the same as any of the case blocks, we can't make it unreachable?

https://alive2.llvm.org/ce/z/ur28cN
Comment 6 Sanjay Patel 2021-08-20 11:41:59 PDT
I think it's safe to resolve this report. I reverted the offending patch with:
https://reviews.llvm.org/rGec54e275f56cc042eb9c25acd

And added a minimal test based on this example:
https://reviews.llvm.org/rG00a50f2617849d0f374d8771f

...so we should not fail in the same way. 

There's still an open question about another potential bug discussed in:
https://reviews.llvm.org/D106056