[PATCH] D122521: Value-number GVNHoist loads by result type as well as pointer address.

Chang Lin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 25 20:44:51 PDT 2022


clin1 created this revision.
clin1 added reviewers: hiraditya, jcranmer-intel.
Herald added a project: All.
clin1 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Avoids merge errors when opaque pointers are loaded into different types.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122521

Files:
  llvm/lib/Transforms/Scalar/GVNHoist.cpp
  llvm/test/Transforms/GVNHoist/opaque-diff-type.ll


Index: llvm/test/Transforms/GVNHoist/opaque-diff-type.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GVNHoist/opaque-diff-type.ll
@@ -0,0 +1,64 @@
+; RUN: opt -opaque-pointers -passes="gvn-hoist" -S %s | FileCheck %s
+
+; Checks that gvn-hoist does not try to merge loads of the same source pointer
+; when the results are different types.
+
+; CHECK: load i16
+; CHECK: load i32
+define linkonce_odr void @i16i32(ptr %arg) {
+bb:
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %tmp = load i16, ptr %arg, align 4
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %tmp3 = load i32, ptr %arg, align 8
+  ret void
+}
+
+; CHECK: load i32
+; CHECK: load float
+define linkonce_odr void @i32f32(ptr %arg) {
+bb:
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %tmp = load i32, ptr %arg, align 4
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %tmp3 = load float, ptr %arg, align 8
+  ret void
+}
+
+; CHECK: load i64
+; CHECK: load ptr
+define linkonce_odr void @i64ptr(ptr %arg) {
+bb:
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %tmp = load i64, ptr %arg, align 4
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %tmp3 = load ptr, ptr %arg, align 8
+  ret void
+}
+
+; CHECK: load ptr
+; CHECK-NOT: load ptr
+define linkonce_odr void @ptrptr(ptr %arg) {
+bb:
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %tmp = load ptr, ptr %arg, align 4
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %tmp3 = load ptr, ptr %arg, align 8
+  ret void
+}
Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -185,7 +185,13 @@
   void insert(LoadInst *Load, GVNPass::ValueTable &VN) {
     if (Load->isSimple()) {
       unsigned V = VN.lookupOrAdd(Load->getPointerOperand());
-      VNtoLoads[{V, InvalidVN}].push_back(Load);
+      // Hash the load's pointer value, result base type, and result size.
+      // With opaque pointers we may have loads from the same pointer with
+      // different result types, which should be disambiguated.
+      Type *LT = Load->getType();
+      // "0" size for pointers is OK, as pointer loads are equivalent.
+      unsigned TypeHash = LT->getTypeID() + (LT->getPrimitiveSizeInBits() << 8);
+      VNtoLoads[{V, TypeHash}].push_back(Load);
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D122521.418374.patch
Type: text/x-patch
Size: 2820 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220326/2791d8ae/attachment.bin>


More information about the llvm-commits mailing list