[NFC][InstCombine] Add miscompile reproducer from https://reviews.llvm.org/D139275...
authorRoman Lebedev <lebedev.ri@gmail.com>
Fri, 16 Dec 2022 16:40:16 +0000 (19:40 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Fri, 16 Dec 2022 17:28:39 +0000 (20:28 +0300)
SimplifyCFG change is correct and not at fault here.
The actual miscompile appears to be happening in InstCombine.

```
$ /builddirs/llvm-project/build-Clang15/bin/opt -load /repositories/alive2/build-Clang-release/tv/tv.so -load-pass-plugin /repositories/alive2/build-Clang-release/tv/tv.so -passes='tv,instcombine,tv' -o /dev/null /repositories/llvm-project/llvm/test/Transforms/InstCombine/D139275_c4001580.ll

----------------------------------------
define float @D139275_c4001580(float %arg) {
%0:
  %i = fcmp ugt float %arg, 0.000000
  %i1 = fcmp ult float %arg, 1.000000
  %i2 = and i1 %i, %i1
  %i3 = fcmp uge float %arg, 0.100000
  %i4 = xor i1 %i, %i2
  %i5 = select i1 %i4, float 0.100000, float 0.000000
  %i6 = and i1 %i3, %i2
  %i7 = fadd float %arg, -0.100000
  %i8 = select i1 %i6, float %i7, float %i5
  ret float %i8
}
=>
define float @D139275_c4001580(float %arg) {
%0:
  %i = fcmp ugt float %arg, 0.000000
  %i1 = fcmp ult float %arg, 1.000000
  %i2 = and i1 %i, %i1
  %i3 = fcmp uge float %arg, 0.100000
  %i7 = fadd float %arg, -0.100000
  %i5 = select i1 %i3, float %i7, float 0.100000
  %i8 = select i1 %i2, float %i5, float 0.000000
  ret float %i8
}
Transformation doesn't verify! (unsound)
ERROR: Value mismatch

Example:
float %arg = #x3dcbb820 (0.099472284317?)

Source:
i1 %i = #x1 (1)
i1 %i1 = #x1 (1)
i1 %i2 = #x1 (1)
i1 %i3 = #x0 (0)
i1 %i4 = #x0 (0)
float %i5 = #x00000000 (+0.0)
i1 %i6 = #x0 (0)
float %i7 = #xba0a5680 (-0.000527717173?)
float %i8 = #x00000000 (+0.0)

Target:
i1 %i = #x1 (1)
i1 %i1 = #x1 (1)
i1 %i2 = #x1 (1)
i1 %i3 = #x0 (0)
float %i7 = #xba0a5680 (-0.000527717173?)
float %i5 = #x3dcccccd (0.100000001490?)
float %i8 = #x3dcccccd (0.100000001490?)
Source value: #x00000000 (+0.0)
Target value: #x3dcccccd (0.100000001490?)

Pass: (anonymous namespace)::TVPass
Command line: '/builddirs/llvm-project/build-Clang15/bin/opt' '-load' '/repositories/alive2/build-Clang-release/tv/tv.so' '-load-pass-plugin' '/repositories/alive2/build-Clang-release/tv/tv.so' '-passes=tv,instcombine,tv' '-o' '/dev/null' '/repositories/llvm-project/llvm/test/Transforms/InstCombine/D139275_c4001580.ll'

Alive2: Transform doesn't verify!

```

llvm/test/Transforms/InstCombine/D139275_c4001580.ll [new file with mode: 0644]
llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll

diff --git a/llvm/test/Transforms/InstCombine/D139275_c4001580.ll b/llvm/test/Transforms/InstCombine/D139275_c4001580.ll
new file mode 100644 (file)
index 0000000..427ef67
--- /dev/null
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+; Based on reproduced from https://reviews.llvm.org/D139275#4001580
+; FIXME: this is a miscompile.
+define float @D139275_c4001580(float %arg) {
+; CHECK-LABEL: @D139275_c4001580(
+; CHECK-NEXT:    [[I:%.*]] = fcmp ugt float [[ARG:%.*]], 0.000000e+00
+; CHECK-NEXT:    [[I1:%.*]] = fcmp ult float [[ARG]], 1.000000e+00
+; CHECK-NEXT:    [[I2:%.*]] = and i1 [[I]], [[I1]]
+; CHECK-NEXT:    [[I3:%.*]] = fcmp uge float [[ARG]], 0x3FB99999A0000000
+; CHECK-NEXT:    [[I7:%.*]] = fadd float [[ARG]], 0xBFB99999A0000000
+; CHECK-NEXT:    [[I5:%.*]] = select i1 [[I3]], float [[I7]], float 0x3FB99999A0000000
+; CHECK-NEXT:    [[I8:%.*]] = select i1 [[I2]], float [[I5]], float 0.000000e+00
+; CHECK-NEXT:    ret float [[I8]]
+;
+  %i = fcmp ugt float %arg, 0.000000e+00
+  %i1 = fcmp ult float %arg, 1.000000e+00
+  %i2 = and i1 %i, %i1
+  %i3 = fcmp uge float %arg, 0x3FB99999A0000000
+  %i4 = xor i1 %i, %i2
+  %i5 = select i1 %i4, float 0x3FB99999A0000000, float 0.000000e+00
+  %i6 = and i1 %i3, %i2
+  %i7 = fadd float %arg, 0xBFB99999A0000000
+  %i8 = select i1 %i6, float %i7, float %i5
+  ret float %i8
+}
index 31b7470..150bdfc 100644 (file)
@@ -453,6 +453,47 @@ final_right:
   call void @sideeffect1.vec(<2 x i8> %final_right.phi.1)
   ret void
 }
+
+; From https://reviews.llvm.org/D139275#4001580
+define float @D139275_c4001580(float %val) {
+; ALL-LABEL: @D139275_c4001580(
+; ALL-NEXT:  entry:
+; ALL-NEXT:    [[CMP:%.*]] = fcmp ugt float [[VAL:%.*]], 0.000000e+00
+; ALL-NEXT:    br i1 [[CMP]], label [[IF_END:%.*]], label [[RETURN:%.*]]
+; ALL:       if.end:
+; ALL-NEXT:    [[CMP1:%.*]] = fcmp ult float [[VAL]], 1.000000e+00
+; ALL-NEXT:    br i1 [[CMP1]], label [[IF_END3:%.*]], label [[RETURN]]
+; ALL:       if.end3:
+; ALL-NEXT:    [[CMP4:%.*]] = fcmp olt float [[VAL]], 0x3FC99999A0000000
+; ALL-NEXT:    br i1 [[CMP4]], label [[RETURN]], label [[IF_END6:%.*]]
+; ALL:       if.end6:
+; ALL-NEXT:    [[SUB:%.*]] = fadd float [[VAL]], 0xBFB99999A0000000
+; ALL-NEXT:    br label [[RETURN]]
+; ALL:       return:
+; ALL-NEXT:    [[RETVAL_0:%.*]] = phi float [ [[SUB]], [[IF_END6]] ], [ 0.000000e+00, [[ENTRY:%.*]] ], [ 0x3FB99999A0000000, [[IF_END]] ], [ 0.000000e+00, [[IF_END3]] ]
+; ALL-NEXT:    ret float [[RETVAL_0]]
+;
+entry:
+  %cmp = fcmp ugt float %val, 0.000000e+00
+  br i1 %cmp, label %if.end, label %return
+
+if.end:
+  %cmp1 = fcmp ult float %val, 1.000000e+00
+  br i1 %cmp1, label %if.end3, label %return
+
+if.end3:
+  %cmp4 = fcmp olt float %val, 0x3FC99999A0000000
+  br i1 %cmp4, label %return, label %if.end6
+
+if.end6:
+  %sub = fadd float %val, 0xBFB99999A0000000
+  br label %return
+
+return:
+  %retval.0 = phi float [ %sub, %if.end6 ], [ 0.000000e+00, %entry ], [ 0x3FB99999A0000000, %if.end ], [ 0.000000e+00, %if.end3 ]
+  ret float %retval.0
+}
+
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
 ; CHEAP: {{.*}}
 ; COSTLY: {{.*}}