From bece10c0fd4760460fba5d2fc7002eea346a7d6c Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 16 Dec 2022 19:40:16 +0300 Subject: [PATCH] [NFC][InstCombine] Add miscompile reproducer from https://reviews.llvm.org/D139275#4001580 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! ``` --- .../Transforms/InstCombine/D139275_c4001580.ll | 27 ++++++++++++++ .../SimplifyCFG/fold-branch-to-common-dest-phis.ll | 41 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/D139275_c4001580.ll diff --git a/llvm/test/Transforms/InstCombine/D139275_c4001580.ll b/llvm/test/Transforms/InstCombine/D139275_c4001580.ll new file mode 100644 index 0000000..427ef67 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/D139275_c4001580.ll @@ -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 +} diff --git a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll index 31b7470..150bdfc 100644 --- a/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll +++ b/llvm/test/Transforms/SimplifyCFG/fold-branch-to-common-dest-phis.ll @@ -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: {{.*}} -- 2.7.4