[llvm] 41e68f7 - [EarlyCSE] Fix and recommit the revised c9826829d74e637163fdb0351870b8204e62d6e6
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 23:16:19 PDT 2020
On Fri, Sep 11, 2020 at 6:31 AM Michael Liao via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
>
>
> Author: Michael Liao
> Date: 2020-09-10T23:30:56-04:00
> New Revision: 41e68f7ee7b3bb33e9acb0502339a858806e8523
>
> URL: https://github.com/llvm/llvm-project/commit/41e68f7ee7b3bb33e9acb0502339a858806e8523
> DIFF: https://github.com/llvm/llvm-project/commit/41e68f7ee7b3bb33e9acb0502339a858806e8523.diff
>
> LOG: [EarlyCSE] Fix and recommit the revised c9826829d74e637163fdb0351870b8204e62d6e6
Nit: commit hashes aren't really meaningful. best to just say
"Recommit: <original subject>"
> In addition to calculate hash consistently by swapping SELECT's
> operands, we also need to inverse the select pattern favor to match the
> original logic.
>
> [EarlyCSE] Equivalent SELECTs should hash equally
>
> DenseMap<SimpleValue> assumes that, if its isEqual method returns true
> for two elements, then its getHashValue method must return the same value
> for them. This invariant is broken when one SELECT node is a min/max
> operation, and the other can be transformed into an equivalent min/max by
> inverting its predicate and swapping its operands. This patch fixes an
> assertion failure that would occur intermittently while compiling the
> following IR:
>
> define i32 @t(i32 %i) {
> %cmp = icmp sle i32 0, %i
> %twin1 = select i1 %cmp, i32 %i, i32 0
> %cmpinv = icmp sgt i32 0, %i
> %twin2 = select i1 %cmpinv, i32 0, i32 %i
> %sink = add i32 %twin1, %twin2
> ret i32 %sink
> }
>
> Differential Revision: https://reviews.llvm.org/D86843
>
> Added:
>
>
> Modified:
> llvm/lib/Transforms/Scalar/EarlyCSE.cpp
> llvm/test/Transforms/EarlyCSE/commute.ll
>
> Removed:
>
>
>
> ################################################################################
> diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
> index b655204d26dd..f71a2b9e003a 100644
> --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
> +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
> @@ -191,11 +191,26 @@ static bool matchSelectWithOptionalNotCond(Value *V, Value *&Cond, Value *&A,
> Pred = ICmpInst::getSwappedPredicate(Pred);
> }
>
> + // Check for inverted variants of min/max by swapping operands.
> + bool Inversed = false;
> switch (Pred) {
> - case CmpInst::ICMP_UGT: Flavor = SPF_UMAX; break;
> - case CmpInst::ICMP_ULT: Flavor = SPF_UMIN; break;
> - case CmpInst::ICMP_SGT: Flavor = SPF_SMAX; break;
> - case CmpInst::ICMP_SLT: Flavor = SPF_SMIN; break;
> + case CmpInst::ICMP_ULE:
> + case CmpInst::ICMP_UGE:
> + case CmpInst::ICMP_SLE:
> + case CmpInst::ICMP_SGE:
> + Pred = CmpInst::getInversePredicate(Pred);
> + std::swap(A, B);
> + Inversed = true;
> + break;
> + default:
> + break;
> + }
> +
> + switch (Pred) {
> + case CmpInst::ICMP_UGT: Flavor = Inversed ? SPF_UMIN : SPF_UMAX; break;
> + case CmpInst::ICMP_ULT: Flavor = Inversed ? SPF_UMAX : SPF_UMIN; break;
> + case CmpInst::ICMP_SGT: Flavor = Inversed ? SPF_SMIN : SPF_SMAX; break;
> + case CmpInst::ICMP_SLT: Flavor = Inversed ? SPF_SMAX : SPF_SMIN; break;
> default: break;
> }
>
>
> diff --git a/llvm/test/Transforms/EarlyCSE/commute.ll b/llvm/test/Transforms/EarlyCSE/commute.ll
> index 57c5a853a12f..a172ba81c652 100644
> --- a/llvm/test/Transforms/EarlyCSE/commute.ll
> +++ b/llvm/test/Transforms/EarlyCSE/commute.ll
> @@ -684,6 +684,26 @@ define i32 @select_not_invert_pred_cond_wrong_select_op(i8 %x, i8 %y, i32 %t, i3
> ret i32 %r
> }
>
> +; This test is a reproducer for a bug involving inverted min/max selects
> +; hashing
> diff erently but comparing as equal. It exhibits such a pair of
> +; values, and we run this test with -earlycse-debug-hash which would catch
> +; the disagreement and fail if it regressed.
> +; EarlyCSE should be able to detect the 2nd redundant `select` and eliminate
> +; it.
> +define i32 @inverted_max(i32 %i) {
> +; CHECK-LABEL: @inverted_max(
> +; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 0, [[I:%.*]]
> +; CHECK-NEXT: [[M1:%.*]] = select i1 [[CMP]], i32 [[I]], i32 0
> +; CHECK-NEXT: [[CMPINV:%.*]] = icmp sgt i32 0, [[I:%.*]]
> +; CHECK-NEXT: [[R:%.*]] = add i32 [[M1]], [[M1]]
> +; CHECK-NEXT: ret i32 [[R]]
> + %cmp = icmp sle i32 0, %i
> + %m1 = select i1 %cmp, i32 %i, i32 0
> + %cmpinv = icmp sgt i32 0, %i
> + %m2 = select i1 %cmpinv, i32 0, i32 %i
> + %r = add i32 %m1, %m2
> + ret i32 %r
> +}
This seems to be the same original test as in the original commit.
Did it expose the additional problem that lead to the revert?
If not, more tests are missing i think.
> ; This test is a reproducer for a bug involving inverted min/max selects
> ; hashing
> diff erently but comparing as equal. It exhibits such a pair of
Roman
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list