mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[GVN] Fix MemorySSA update when replacing assume(false) with stores.
When replacing an assume(false) with a store, we have to be more careful with the order we insert the new access. This patch updates the code to look at the accesses in the block to find a suitable insertion point. Alterantively we could check the defining access of the assume, but IIRC there has been some discussion about making assume() readnone, so looking at the access list might be more future proof. Fixes PR48072. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D90784
This commit is contained in:
parent
6e930ff849
commit
0fbc387566
@ -1605,12 +1605,35 @@ bool GVN::processAssumeIntrinsic(IntrinsicInst *IntrinsicI) {
|
||||
Constant::getNullValue(Int8Ty->getPointerTo()),
|
||||
IntrinsicI);
|
||||
if (MSSAU) {
|
||||
const MemoryUseOrDef *FirstNonDom = nullptr;
|
||||
const auto *AL =
|
||||
MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->getParent());
|
||||
|
||||
// If there are accesses in the current basic block, find the first one
|
||||
// that does not come before NewS. The new memory access is inserted
|
||||
// after the found access or before the terminator if no such access is
|
||||
// found.
|
||||
if (AL) {
|
||||
for (auto &Acc : *AL) {
|
||||
if (auto *Current = dyn_cast<MemoryUseOrDef>(&Acc))
|
||||
if (!Current->getMemoryInst()->comesBefore(NewS)) {
|
||||
FirstNonDom = Current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This added store is to null, so it will never executed and we can
|
||||
// just use the LiveOnEntry def as defining access.
|
||||
auto *NewDef = MSSAU->createMemoryAccessInBB(
|
||||
NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(), NewS->getParent(),
|
||||
MemorySSA::BeforeTerminator);
|
||||
MSSAU->insertDef(cast<MemoryDef>(NewDef), /*RenameUses=*/true);
|
||||
auto *NewDef =
|
||||
FirstNonDom ? MSSAU->createMemoryAccessBefore(
|
||||
NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
|
||||
const_cast<MemoryUseOrDef *>(FirstNonDom))
|
||||
: MSSAU->createMemoryAccessInBB(
|
||||
NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
|
||||
NewS->getParent(), MemorySSA::BeforeTerminator);
|
||||
|
||||
MSSAU->insertDef(cast<MemoryDef>(NewDef), /*RenameUses=*/false);
|
||||
}
|
||||
}
|
||||
if (isAssumeWithEmptyBundle(*IntrinsicI))
|
||||
|
@ -93,3 +93,56 @@ for.body830:
|
||||
for.body.i22:
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
define void @test_assume_false_to_store_undef_1(i32* %ptr) {
|
||||
; CHECK-LABEL: @test_assume_false_to_store_undef_1(
|
||||
; CHECK-NEXT: store i32 10, i32* [[PTR:%.*]], align 4
|
||||
; CHECK-NEXT: store i8 undef, i8* null, align 1
|
||||
; CHECK-NEXT: call void @f()
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
store i32 10, i32* %ptr
|
||||
%tobool = icmp ne i16 1, 0
|
||||
%xor = xor i1 %tobool, true
|
||||
call void @llvm.assume(i1 %xor)
|
||||
call void @f()
|
||||
ret void
|
||||
}
|
||||
|
||||
define i32 @test_assume_false_to_store_undef_2(i32* %ptr, i32* %ptr.2) {
|
||||
; CHECK-LABEL: @test_assume_false_to_store_undef_2(
|
||||
; CHECK-NEXT: store i32 10, i32* [[PTR:%.*]], align 4
|
||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_2:%.*]], align 4
|
||||
; CHECK-NEXT: store i8 undef, i8* null, align 1
|
||||
; CHECK-NEXT: call void @f()
|
||||
; CHECK-NEXT: ret i32 [[LV]]
|
||||
;
|
||||
store i32 10, i32* %ptr
|
||||
%lv = load i32, i32* %ptr.2
|
||||
%tobool = icmp ne i16 1, 0
|
||||
%xor = xor i1 %tobool, true
|
||||
call void @llvm.assume(i1 %xor)
|
||||
call void @f()
|
||||
ret i32 %lv
|
||||
}
|
||||
|
||||
define i32 @test_assume_false_to_store_undef_3(i32* %ptr, i32* %ptr.2) {
|
||||
; CHECK-LABEL: @test_assume_false_to_store_undef_3(
|
||||
; CHECK-NEXT: store i32 10, i32* [[PTR:%.*]], align 4
|
||||
; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[PTR_2:%.*]], align 4
|
||||
; CHECK-NEXT: store i8 undef, i8* null, align 1
|
||||
; CHECK-NEXT: ret i32 [[LV]]
|
||||
;
|
||||
store i32 10, i32* %ptr
|
||||
%lv = load i32, i32* %ptr.2
|
||||
%tobool = icmp ne i16 1, 0
|
||||
%xor = xor i1 %tobool, true
|
||||
call void @llvm.assume(i1 %xor)
|
||||
ret i32 %lv
|
||||
}
|
||||
|
||||
declare void @f()
|
||||
|
||||
declare void @llvm.assume(i1 noundef) #0
|
||||
|
||||
attributes #0 = { nofree nosync nounwind willreturn }
|
||||
|
Loading…
Reference in New Issue
Block a user