forked from OSchip/llvm-project
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
This commit is contained in:
parent
85eae45520
commit
c28ce745cf
|
@ -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 @@ public:
|
|||
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
|
||||
// different result types, which should be disambiguated.
|
||||
VNtoLoads[{V, (uintptr_t)Load->getType()}].push_back(Load);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 different 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
|
||||
}
|
Loading…
Reference in New Issue