[GVNHoist] Don't wrongly preserve TBAA
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 21 Jul 2016 05:59:53 +0000 (05:59 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 21 Jul 2016 05:59:53 +0000 (05:59 +0000)
We hoisted loads/stores without taking into account which can cause
miscompiles.

llvm-svn: 276240

llvm/lib/Transforms/Scalar/GVNHoist.cpp
llvm/test/Transforms/GVN/hoist-md.ll [new file with mode: 0644]

index 494f36b..9ca6ea0 100644 (file)
@@ -603,12 +603,20 @@ public:
     // Copy the gep before moving the ld/st.
     Instruction *ClonedGep = Gep->clone();
     ClonedGep->insertBefore(HoistPt->getTerminator());
+    // Conservatively discard any optimization hints, they may differ on the
+    // other paths.
+    ClonedGep->dropUnknownNonDebugMetadata();
+    ClonedGep->clearSubclassOptionalData();
     Repl->replaceUsesOfWith(Gep, ClonedGep);
 
     // Also copy Val.
     if (Val) {
       Instruction *ClonedVal = Val->clone();
       ClonedVal->insertBefore(HoistPt->getTerminator());
+      // Conservatively discard any optimization hints, they may differ on the
+      // other paths.
+      ClonedVal->dropUnknownNonDebugMetadata();
+      ClonedVal->clearSubclassOptionalData();
       Repl->replaceUsesOfWith(Val, ClonedVal);
     }
 
@@ -647,6 +655,9 @@ public:
             !makeOperandsAvailable(Repl, HoistPt))
           continue;
         Repl->moveBefore(HoistPt->getTerminator());
+        // TBAA may differ on one of the other paths, we need to get rid of
+        // anything which might conflict.
+        Repl->dropUnknownNonDebugMetadata();
       }
 
       if (isa<LoadInst>(Repl))
@@ -668,6 +679,7 @@ public:
             ++NumStoresRemoved;
           else if (isa<CallInst>(Repl))
             ++NumCallsRemoved;
+          Repl->intersectOptionalDataWith(I);
           I->replaceAllUsesWith(Repl);
           I->eraseFromParent();
         }
diff --git a/llvm/test/Transforms/GVN/hoist-md.ll b/llvm/test/Transforms/GVN/hoist-md.ll
new file mode 100644 (file)
index 0000000..14cc848
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: opt -S -gvn-hoist < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test1(i1 %b, i32* %x) {
+entry:
+  br i1 %b, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  store i32 2, i32* %x, align 4, !tbaa !1
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  store i32 2, i32* %x, align 4, !tbaa !5
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+; CHECK-LABEL: define void @test1(
+; CHECK: store i32 2, i32* %x, align 4
+; CHECK-NEXT: br i1 %b
+
+!1 = !{!2, !2, i64 0}
+!2 = !{!"int", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C++ TBAA"}
+!5 = !{!6, !6, i64 0}
+!6 = !{!"_ZTS1e", !3, i64 0}