[llvm] c28ce74 - Value-number GVNHoist loads by result type as well as pointer address.
Chang-Sun Lin Jr via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 30 11:33:57 PDT 2022
Author: Chang-Sun Lin Jr
Date: 2022-03-30T11:33:49-07:00
New Revision: c28ce745cf1917dedee66719281ac2d5741637f0
URL: https://github.com/llvm/llvm-project/commit/c28ce745cf1917dedee66719281ac2d5741637f0
DIFF: https://github.com/llvm/llvm-project/commit/c28ce745cf1917dedee66719281ac2d5741637f0.diff
LOG: Value-number GVNHoist loads by result type as well as pointer address.
Avoids merge errors when opaque pointers are loaded into different types.
Reviewed by: jcranmer-intel, hiraditya
Differential Revision: https://reviews.llvm.org/D122521
Added:
llvm/test/Transforms/GVNHoist/opaque-diff-type.ll
Modified:
llvm/lib/Transforms/Scalar/GVNHoist.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp
index 4028218b3827b..dafa9f8b5c7e8 100644
--- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp
+++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp
@@ -124,7 +124,7 @@ using HoistingPointInfo = std::pair<BasicBlock *, SmallVecInsn>;
using HoistingPointList = SmallVector<HoistingPointInfo, 4>;
// A map from a pair of VNs to all the instructions with those VNs.
-using VNType = std::pair<unsigned, unsigned>;
+using VNType = std::pair<unsigned, uintptr_t>;
using VNtoInsns = DenseMap<VNType, SmallVector<Instruction *, 4>>;
@@ -159,7 +159,7 @@ using InValuesType =
// An invalid value number Used when inserting a single value number into
// VNtoInsns.
-enum : unsigned { InvalidVN = ~2U };
+enum : uintptr_t { InvalidVN = ~(uintptr_t)2 };
// Records all scalar instructions candidate for code hoisting.
class InsnInfo {
@@ -185,7 +185,9 @@ class LoadInfo {
void insert(LoadInst *Load, GVNPass::ValueTable &VN) {
if (Load->isSimple()) {
unsigned V = VN.lookupOrAdd(Load->getPointerOperand());
- VNtoLoads[{V, InvalidVN}].push_back(Load);
+ // With opaque pointers we may have loads from the same pointer with
+ //
diff erent result types, which should be disambiguated.
+ VNtoLoads[{V, (uintptr_t)Load->getType()}].push_back(Load);
}
}
diff --git a/llvm/test/Transforms/GVNHoist/opaque-
diff -type.ll b/llvm/test/Transforms/GVNHoist/opaque-
diff -type.ll
new file mode 100644
index 0000000000000..c36f8de311bbd
--- /dev/null
+++ b/llvm/test/Transforms/GVNHoist/opaque-
diff -type.ll
@@ -0,0 +1,119 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; 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
diff erent types.
+
+define linkonce_odr void @i16i32(ptr %arg) {
+; CHECK-LABEL: @i16i32(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[T:%.*]] = load i16, ptr [[ARG:%.*]], align 4
+; CHECK-NEXT: br label [[BB2]]
+; CHECK: bb2:
+; CHECK-NEXT: [[T3:%.*]] = load i32, ptr [[ARG]], align 8
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %t = load i16, ptr %arg, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %t3 = load i32, ptr %arg, align 8
+ ret void
+}
+
+define linkonce_odr void @i32f32(ptr %arg) {
+; CHECK-LABEL: @i32f32(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[T:%.*]] = load i32, ptr [[ARG:%.*]], align 4
+; CHECK-NEXT: br label [[BB2]]
+; CHECK: bb2:
+; CHECK-NEXT: [[T3:%.*]] = load float, ptr [[ARG]], align 8
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %t = load i32, ptr %arg, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %t3 = load float, ptr %arg, align 8
+ ret void
+}
+
+define linkonce_odr void @i64ptr(ptr %arg) {
+; CHECK-LABEL: @i64ptr(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[T:%.*]] = load i64, ptr [[ARG:%.*]], align 4
+; CHECK-NEXT: br label [[BB2]]
+; CHECK: bb2:
+; CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[ARG]], align 8
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %t = load i64, ptr %arg, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %t3 = load ptr, ptr %arg, align 8
+ ret void
+}
+
+define linkonce_odr void @ptrptr_
diff _aspace(ptr %arg) {
+; CHECK-LABEL: @ptrptr_
diff _aspace(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: [[T:%.*]] = load ptr addrspace(4), ptr [[ARG:%.*]], align 4
+; CHECK-NEXT: br label [[BB2]]
+; CHECK: bb2:
+; CHECK-NEXT: [[T3:%.*]] = load ptr addrspace(2), ptr [[ARG]], align 8
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %t = load ptr addrspace(4), ptr %arg, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %t3 = load ptr addrspace(2), ptr %arg, align 8
+ ret void
+}
+
+define linkonce_odr void @ptrptr(ptr %arg) {
+; CHECK-LABEL: @ptrptr(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[ARG:%.*]], align 4
+; CHECK-NEXT: br i1 false, label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: br label [[BB2]]
+; CHECK: bb2:
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ %t = load ptr, ptr %arg, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %t3 = load ptr, ptr %arg, align 8
+ ret void
+}
More information about the llvm-commits
mailing list