mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[SCCP] Support ranges for loads and stores.
Integer ranges can be used for loaded/stored values. Note that widening can be disabled for loads/stores, as we only rely on instructions that cause continued increases to ranges to be widened (like binary operators). Reviewers: efriedma, mssimpso, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D78433
This commit is contained in:
parent
924a8344f0
commit
2f937465a7
@ -1071,8 +1071,9 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the value we are storing into the global, then merge it.
|
// Get the value we are storing into the global, then merge it.
|
||||||
mergeInValue(I->second, GV, getValueState(SI.getOperand(0)));
|
mergeInValue(I->second, GV, getValueState(SI.getOperand(0)),
|
||||||
if (isOverdefined(I->second))
|
ValueLatticeElement::MergeOptions().setCheckWiden(false));
|
||||||
|
if (I->second.isOverdefined())
|
||||||
TrackedGlobals.erase(I); // No need to keep tracking this!
|
TrackedGlobals.erase(I); // No need to keep tracking this!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,7 +1086,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
|
|||||||
|
|
||||||
// ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
|
// ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
|
||||||
// discover a concrete value later.
|
// discover a concrete value later.
|
||||||
if (isOverdefined(ValueState[&I]))
|
if (ValueState[&I].isOverdefined())
|
||||||
return (void)markOverdefined(&I);
|
return (void)markOverdefined(&I);
|
||||||
|
|
||||||
ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
|
ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
|
||||||
@ -1113,7 +1114,8 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
|
|||||||
// If we are tracking this global, merge in the known value for it.
|
// If we are tracking this global, merge in the known value for it.
|
||||||
auto It = TrackedGlobals.find(GV);
|
auto It = TrackedGlobals.find(GV);
|
||||||
if (It != TrackedGlobals.end()) {
|
if (It != TrackedGlobals.end()) {
|
||||||
mergeInValue(IV, &I, It->second);
|
mergeInValue(IV, &I, It->second,
|
||||||
|
ValueLatticeElement::MergeOptions().setCheckWiden(false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,10 @@ declare void @use(i1)
|
|||||||
define void @test1a() {
|
define void @test1a() {
|
||||||
; CHECK-LABEL: @test1a(
|
; CHECK-LABEL: @test1a(
|
||||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @G
|
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @G
|
||||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[X]], 124
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
|
||||||
; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[X]], 123
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_2]])
|
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
@ -59,14 +55,10 @@ F:
|
|||||||
define void @test2a() {
|
define void @test2a() {
|
||||||
; CHECK-LABEL: @test2a(
|
; CHECK-LABEL: @test2a(
|
||||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @H
|
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @H
|
||||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[X]], 124
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
|
||||||
; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[X]], 123
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_2]])
|
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
@ -123,14 +115,10 @@ F:
|
|||||||
define void @test3a() {
|
define void @test3a() {
|
||||||
; CHECK-LABEL: @test3a(
|
; CHECK-LABEL: @test3a(
|
||||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @I
|
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @I
|
||||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i32 [[X]], 124
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[X]], 124
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
|
||||||
; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[X]], 123
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_2]])
|
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
@ -245,19 +233,15 @@ exit:
|
|||||||
|
|
||||||
; Same as test1, but storing 4 different values.
|
; Same as test1, but storing 4 different values.
|
||||||
|
|
||||||
@K = internal global i32 0
|
@K = internal global i32 501
|
||||||
|
|
||||||
define void @test5a() {
|
define void @test5a() {
|
||||||
; CHECK-LABEL: @test5a(
|
; CHECK-LABEL: @test5a(
|
||||||
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @K
|
; CHECK-NEXT: [[X:%.*]] = load i32, i32* @K
|
||||||
; CHECK-NEXT: [[T_1:%.*]] = icmp ne i32 [[X]], 499
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_1]])
|
; CHECK-NEXT: call void @use(i1 true)
|
||||||
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i32 [[X]], 600
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: call void @use(i1 [[T_2]])
|
; CHECK-NEXT: call void @use(i1 false)
|
||||||
; CHECK-NEXT: [[F_1:%.*]] = icmp eq i32 [[X]], 600
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_1]])
|
|
||||||
; CHECK-NEXT: [[F_2:%.*]] = icmp ugt i32 [[X]], 600
|
|
||||||
; CHECK-NEXT: call void @use(i1 [[F_2]])
|
|
||||||
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 510
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 510
|
||||||
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
; CHECK-NEXT: call void @use(i1 [[C_1]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
@ -319,5 +303,4 @@ T.3:
|
|||||||
F.3:
|
F.3:
|
||||||
store i32 530, i32* @K
|
store i32 530, i32* @K
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user