From: Davide Italiano Date: Fri, 19 May 2017 04:06:10 +0000 (+0000) Subject: [NewGVN] Delete the old store when we find congruent to a load. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd8c7210cda8d7baa37bdf511ad0dac8408f7d5d;p=llvm [NewGVN] Delete the old store when we find congruent to a load. (or non-store, more in general). Fixes PR33086. Caught by the store verifier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303406 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 0b6f75093aa..4b6a2fd7fda 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -2111,11 +2111,11 @@ void NewGVN::performCongruenceFinding(Instruction *I, const Expression *E) { // old store expression. In particular, loads do not compare against stored // value, so they will find old store expressions (and associated class // mappings) if we leave them in the table. - if (ClassChanged && isa(E)) { + if (ClassChanged && isa(I)) { auto *OldE = ValueToExpression.lookup(I); // It could just be that the old class died. We don't want to erase it if we // just moved classes. - if (OldE && isa(OldE) && !OldE->equals(*E)) + if (OldE && isa(OldE) && *E != *OldE) ExpressionToClass.erase(OldE); } ValueToExpression[I] = E; diff --git a/test/Transforms/NewGVN/pr33086.ll b/test/Transforms/NewGVN/pr33086.ll new file mode 100644 index 00000000000..6117ef35e6d --- /dev/null +++ b/test/Transforms/NewGVN/pr33086.ll @@ -0,0 +1,59 @@ +; RUN: opt -newgvn -S %s | FileCheck %s +; REQUIRES: asserts + +; CHECK-LABEL: define void @tinkywinky() { +; CHECK: entry: +; CHECK-NEXT: br i1 undef, label %for.cond18, label %for.cond.preheader +; CHECK: for.cond.preheader: +; CHECK-NEXT: br label %for.cond2thread-pre-split +; CHECK: for.cond2thread-pre-split: +; CHECK-NEXT: %conv24 = phi i32 [ 0, %for.cond.preheader ], [ %conv, %for.inc.split ] +; CHECK-NEXT: br label %for.inc.split +; CHECK: for.inc.split: +; CHECK-NEXT: %add = shl nsw i32 %conv24, 16 +; CHECK-NEXT: %sext23 = add i32 %add, 65536 +; CHECK-NEXT: %conv = ashr exact i32 %sext23, 16 +; CHECK-NEXT: %cmp = icmp slt i32 %sext23, 3604480 +; CHECK-NEXT: br i1 %cmp, label %for.cond2thread-pre-split, label %l1.loopexit +; CHECK: l1.loopexit: +; CHECK-NEXT: br label %l1 +; CHECK: l1: +; CHECK-NEXT: %0 = load i16, i16* null, align 2 +; CHECK-NEXT: %g.0.g.0..pr = load i16, i16* null, align 2 +; CHECK-NEXT: ret void +; CHECK: for.cond18: +; CHECK-NEXT: br label %l1 +; CHECK-NEXT: } + +define void @tinkywinky() { +entry: + br i1 undef, label %for.cond18, label %for.cond.preheader + +for.cond.preheader: + br label %for.cond2thread-pre-split + +for.cond2thread-pre-split: + %conv24 = phi i32 [ 0, %for.cond.preheader ], [ %conv, %for.inc.split ] + br label %for.inc.split + +for.inc.split: + %add = shl nsw i32 %conv24, 16 + %sext23 = add i32 %add, 65536 + %conv = ashr exact i32 %sext23, 16 + %cmp = icmp slt i32 %sext23, 3604480 + br i1 %cmp, label %for.cond2thread-pre-split, label %l1.loopexit + +l1.loopexit: + br label %l1 + +l1: + %h.0 = phi i16* [ undef, %for.cond18 ], [ null, %l1.loopexit ] + %0 = load i16, i16* %h.0, align 2 + store i16 %0, i16* null, align 2 + %g.0.g.0..pr = load i16, i16* null, align 2 + %tobool15 = icmp eq i16 %g.0.g.0..pr, 0 + ret void + +for.cond18: + br label %l1 +}