Skip to content

Commit 629addc

Browse files
committed
[InstCombine] Support offsets in memset to load forwarding
Adds support for load offsets when performing `memset` to load forwarding.
1 parent 3ca67bc commit 629addc

File tree

3 files changed

+16
-15
lines changed

3 files changed

+16
-15
lines changed

llvm/lib/Analysis/Loads.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,9 +631,14 @@ static Value *getAvailableLoadStore(Instruction *Inst, const Value *Ptr,
631631
if (!Val || !Len)
632632
return nullptr;
633633

634-
// TODO: Handle offsets.
635-
Value *Dst = MSI->getDest();
636-
if (!AreEquivalentAddressValues(Dst, Ptr))
634+
// Handle offsets.
635+
int64_t StoreOffset = 0, LoadOffset = 0;
636+
const Value *StoreBase =
637+
GetPointerBaseWithConstantOffset(MSI->getDest(), StoreOffset, DL);
638+
const Value *LoadBase =
639+
GetPointerBaseWithConstantOffset(Ptr, LoadOffset, DL);
640+
int64_t Offset = LoadOffset - StoreOffset;
641+
if (StoreBase != LoadBase || Offset < 0)
637642
return nullptr;
638643

639644
if (IsLoadCSE)
@@ -645,7 +650,11 @@ static Value *getAvailableLoadStore(Instruction *Inst, const Value *Ptr,
645650

646651
// Make sure the read bytes are contained in the memset.
647652
uint64_t LoadSize = LoadTypeSize.getFixedValue();
648-
if ((Len->getValue() * 8).ult(LoadSize))
653+
if ((Len->getValue() * 8).ult(LoadSize + Offset * 8))
654+
return nullptr;
655+
656+
// If there is an offset, make sure the load size is a multiple of 8.
657+
if (Offset && LoadSize % 8 != 0)
649658
return nullptr;
650659

651660
APInt Splat = LoadSize >= 8 ? APInt::getSplat(LoadSize, Val->getValue())

llvm/test/Analysis/GlobalsModRef/memset-escape.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@ target triple = "x86_64-apple-macosx10.10.0"
1010
; @a after the memset.
1111

1212
; CHECK-LABEL: @main
13-
; CHECK: call void @llvm.memset.p0.i64{{.*}} @a
1413
; CHECK: store i32 3
15-
; CHECK: load i32, ptr getelementptr {{.*}} @a
16-
; CHECK: icmp eq i32
17-
; CHECK: br i1
14+
; CHECK: ret i32 0
1815

1916
define i32 @main() {
2017
entry:

llvm/test/Transforms/InstCombine/load-store-forward.ll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,10 @@ define i32 @load_after_memset_unknown(ptr %a, i8 %byte) {
365365
ret i32 %v
366366
}
367367

368-
; TODO: Handle load at offset.
369368
define i32 @load_after_memset_0_offset(ptr %a) {
370369
; CHECK-LABEL: @load_after_memset_0_offset(
371370
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) [[A:%.*]], i8 0, i64 16, i1 false)
372-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 4
373-
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
374-
; CHECK-NEXT: ret i32 [[V]]
371+
; CHECK-NEXT: ret i32 0
375372
;
376373
call void @llvm.memset.p0.i64(ptr %a, i8 0, i64 16, i1 false)
377374
%gep = getelementptr i8, ptr %a, i64 4
@@ -382,9 +379,7 @@ define i32 @load_after_memset_0_offset(ptr %a) {
382379
define i32 @load_after_memset_1_offset(ptr %a) {
383380
; CHECK-LABEL: @load_after_memset_1_offset(
384381
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(16) [[A:%.*]], i8 1, i64 16, i1 false)
385-
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[A]], i64 4
386-
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[GEP]], align 4
387-
; CHECK-NEXT: ret i32 [[V]]
382+
; CHECK-NEXT: ret i32 16843009
388383
;
389384
call void @llvm.memset.p0.i64(ptr %a, i8 1, i64 16, i1 false)
390385
%gep = getelementptr i8, ptr %a, i64 4

0 commit comments

Comments
 (0)