Skip to content

Commit d83fdfb

Browse files
committed
Fix logic for alignment of stores in memset.pattern expansion
1 parent 30d59b9 commit d83fdfb

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

llvm/lib/Transforms/Utils/LowerMemIntrinsics.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ static void createMemSetPatternLoop(Instruction *InsertBefore, Value *DstAddr,
461461
Align DstAlign, bool IsVolatile) {
462462
BasicBlock *OrigBB = InsertBefore->getParent();
463463
Function *F = OrigBB->getParent();
464+
const DataLayout &DL = F->getDataLayout();
464465

465466
Type *TypeOfCount = Count->getType();
466467

@@ -480,7 +481,9 @@ static void createMemSetPatternLoop(Instruction *InsertBefore, Value *DstAddr,
480481
PHINode *LoopCount = LoopBuilder.CreatePHI(TypeOfCount, 0);
481482
LoopCount->addIncoming(Count, OrigBB);
482483

483-
LoopBuilder.CreateAlignedStore(SetValue, CurrentDst, DstAlign, IsVolatile);
484+
unsigned PatSize = DL.getTypeStoreSize(SetValue->getType());
485+
Align PatAlign(commonAlignment(DstAlign, PatSize));
486+
LoopBuilder.CreateAlignedStore(SetValue, CurrentDst, PatAlign, IsVolatile);
484487

485488
Value *NextDst = LoopBuilder.CreateInBoundsGEP(
486489
SetValue->getType(), CurrentDst, ConstantInt::get(TypeOfCount, 1));

llvm/test/Transforms/PreISelIntrinsicLowering/RISCV/memset-pattern.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,37 @@ define void @memset_pattern_i256_x(ptr %a, i256 %value, i64 %x) nounwind {
9898
tail call void @llvm.memset.pattern(ptr %a, i256 %value, i64 %x, i1 0)
9999
ret void
100100
}
101+
102+
; The common alignment of the allocation of the pattern stride (its allocation
103+
; size) and the destination pointer should be used.
104+
define void @memset_pattern_i15_x_alignment(ptr %a, i15 %value, i64 %x) nounwind {
105+
; CHECK-LABEL: define void @memset_pattern_i15_x_alignment(
106+
; CHECK-SAME: ptr [[A:%.*]], i15 [[VALUE:%.*]], i64 [[X:%.*]]) #[[ATTR0]] {
107+
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 0, [[X]]
108+
; CHECK-NEXT: br i1 [[TMP1]], label %[[SPLIT:.*]], label %[[STORELOOP:.*]]
109+
; CHECK: [[STORELOOP]]:
110+
; CHECK-NEXT: [[TMP2:%.*]] = phi ptr [ [[A]], [[TMP0:%.*]] ], [ [[TMP4:%.*]], %[[STORELOOP]] ]
111+
; CHECK-NEXT: [[TMP3:%.*]] = phi i64 [ [[X]], [[TMP0]] ], [ [[TMP5:%.*]], %[[STORELOOP]] ]
112+
; CHECK-NEXT: store i15 [[VALUE]], ptr [[TMP2]], align 1
113+
; CHECK-NEXT: [[TMP4]] = getelementptr inbounds i15, ptr [[TMP2]], i64 1
114+
; CHECK-NEXT: [[TMP5]] = sub i64 [[TMP3]], 1
115+
; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i64 [[TMP5]], 0
116+
; CHECK-NEXT: br i1 [[TMP6]], label %[[STORELOOP]], label %[[SPLIT]]
117+
; CHECK: [[SPLIT]]:
118+
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 0, [[X]]
119+
; CHECK-NEXT: br i1 [[TMP7]], label %[[SPLIT1:.*]], label %[[STORELOOP2:.*]]
120+
; CHECK: [[STORELOOP2]]:
121+
; CHECK-NEXT: [[TMP8:%.*]] = phi ptr [ [[A]], %[[SPLIT]] ], [ [[TMP10:%.*]], %[[STORELOOP2]] ]
122+
; CHECK-NEXT: [[TMP9:%.*]] = phi i64 [ [[X]], %[[SPLIT]] ], [ [[TMP11:%.*]], %[[STORELOOP2]] ]
123+
; CHECK-NEXT: store i15 [[VALUE]], ptr [[TMP8]], align 2
124+
; CHECK-NEXT: [[TMP10]] = getelementptr inbounds i15, ptr [[TMP8]], i64 1
125+
; CHECK-NEXT: [[TMP11]] = sub i64 [[TMP9]], 1
126+
; CHECK-NEXT: [[TMP12:%.*]] = icmp ne i64 [[TMP11]], 0
127+
; CHECK-NEXT: br i1 [[TMP12]], label %[[STORELOOP2]], label %[[SPLIT1]]
128+
; CHECK: [[SPLIT1]]:
129+
; CHECK-NEXT: ret void
130+
;
131+
call void @llvm.memset.pattern(ptr align 1 %a, i15 %value, i64 %x, i1 0)
132+
call void @llvm.memset.pattern(ptr align 2 %a, i15 %value, i64 %x, i1 0)
133+
ret void
134+
}

0 commit comments

Comments
 (0)