Remove the special casing for intrinsics in MemoryLocation::getForDest() and handle them through the general attribute based code. On the DSE side, this means that isRemovable() now needs to handle more than a hardcoded list of intrinsics. We consider everything apart from volatile memory intrinsics and lifetime markers to be removable. This allows us to perform DSE on intrinsics that DSE has not been specially taught about, using a matrix store as an example here. There is an interesting test change for invariant.start, but I believe that optimization is correct. It only looks a bit odd because the code is immediate UB anyway. Differential Revision: https://reviews.llvm.org/D116210
38 lines
1.3 KiB
LLVM
38 lines
1.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; Test to make sure llvm.invariant.start calls are not treated as clobbers.
|
|
; RUN: opt < %s -basic-aa -dse -S | FileCheck %s
|
|
|
|
declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) nounwind readonly
|
|
|
|
; We could remove either store here. The first store is dead in the
|
|
; conventional sense, because there is a later killing store. The second store
|
|
; is undefined behavior by the semantics of invariant.start, and as such
|
|
; unreachable.
|
|
define void @test(i8 *%p) {
|
|
; CHECK-LABEL: @test(
|
|
; CHECK-NEXT: store i8 3, i8* [[P:%.*]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
store i8 1, i8* %p, align 4
|
|
%i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %p)
|
|
store i8 3, i8* %p, align 4
|
|
ret void
|
|
}
|
|
|
|
; FIXME: We should be able to remove the first store to p, even though p and q
|
|
; may alias.
|
|
define void @test2(i8* %p, i8* %q) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: store i8 1, i8* [[P:%.*]], align 4
|
|
; CHECK-NEXT: store i8 2, i8* [[Q:%.*]], align 4
|
|
; CHECK-NEXT: [[I:%.*]] = call {}* @llvm.invariant.start.p0i8(i64 1, i8* [[Q]])
|
|
; CHECK-NEXT: store i8 3, i8* [[P]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
store i8 1, i8* %p, align 4
|
|
store i8 2, i8* %q, align 4
|
|
%i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %q)
|
|
store i8 3, i8* %p, align 4
|
|
ret void
|
|
}
|