]> granicus.if.org Git - llvm/commitdiff
[NewGVN] Delete the old store when we find congruent to a load.
authorDavide Italiano <davide@freebsd.org>
Fri, 19 May 2017 04:06:10 +0000 (04:06 +0000)
committerDavide Italiano <davide@freebsd.org>
Fri, 19 May 2017 04:06:10 +0000 (04:06 +0000)
(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

lib/Transforms/Scalar/NewGVN.cpp
test/Transforms/NewGVN/pr33086.ll [new file with mode: 0644]

index 0b6f75093aa2a1016be5ee027231ac915958c971..4b6a2fd7fda6b49777ac2b7a626a752467f32d95 100644 (file)
@@ -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<StoreExpression>(E)) {
+  if (ClassChanged && isa<StoreInst>(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<StoreExpression>(OldE) && !OldE->equals(*E))
+    if (OldE && isa<StoreExpression>(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 (file)
index 0000000..6117ef3
--- /dev/null
@@ -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
+}