Skip to content

Commit 905f4eb

Browse files
committed
[SROA] Avoid splitting loads/stores with irregular type
Upon encountering loads/stores on types whose size is not a multiple of 8 bits the SROA pass would either trip an assertion or use logic that was not meant to work with such irregularly-sized types. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D99435
1 parent 391f9ef commit 905f4eb

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,8 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
768768
// We allow splitting of non-volatile loads and stores where the type is an
769769
// integer type. These may be used to implement 'memcpy' or other "transfer
770770
// of bits" patterns.
771-
bool IsSplittable = Ty->isIntegerTy() && !IsVolatile;
771+
bool IsSplittable =
772+
Ty->isIntegerTy() && !IsVolatile && DL.typeSizeEqualsStoreSize(Ty);
772773

773774
insertUse(I, Offset, Size, IsSplittable);
774775
}
@@ -3989,6 +3990,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
39893990
SplitLoads.clear();
39903991

39913992
IntegerType *Ty = cast<IntegerType>(LI->getType());
3993+
assert(Ty->getBitWidth() % 8 == 0);
39923994
uint64_t LoadSize = Ty->getBitWidth() / 8;
39933995
assert(LoadSize > 0 && "Cannot have a zero-sized integer load!");
39943996

@@ -4113,6 +4115,7 @@ bool SROA::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
41134115
for (StoreInst *SI : Stores) {
41144116
auto *LI = cast<LoadInst>(SI->getValueOperand());
41154117
IntegerType *Ty = cast<IntegerType>(LI->getType());
4118+
assert(Ty->getBitWidth() % 8 == 0);
41164119
uint64_t StoreSize = Ty->getBitWidth() / 8;
41174120
assert(StoreSize > 0 && "Cannot have a zero-sized integer store!");
41184121

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -sroa -S | FileCheck %s
3+
4+
%S = type { [4 x i8] }
5+
6+
; Ensure the load/store of integer types whose size is not equal to the store
7+
; size are not split.
8+
9+
define i8 @foo(i23 %0) {
10+
; CHECK-LABEL: @foo(
11+
; CHECK-NEXT: Entry:
12+
; CHECK-NEXT: [[DOTSROA_0:%.*]] = alloca [3 x i8], align 8
13+
; CHECK-NEXT: [[DOTSROA_0_0__SROA_CAST1:%.*]] = bitcast [3 x i8]* [[DOTSROA_0]] to i23*
14+
; CHECK-NEXT: store i23 [[TMP0:%.*]], i23* [[DOTSROA_0_0__SROA_CAST1]], align 8
15+
; CHECK-NEXT: [[DOTSROA_0_1__SROA_IDX2:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* [[DOTSROA_0]], i64 0, i64 1
16+
; CHECK-NEXT: [[DOTSROA_0_1__SROA_0_1_:%.*]] = load i8, i8* [[DOTSROA_0_1__SROA_IDX2]], align 1
17+
; CHECK-NEXT: ret i8 [[DOTSROA_0_1__SROA_0_1_]]
18+
;
19+
Entry:
20+
%1 = alloca %S
21+
%2 = bitcast %S* %1 to i23*
22+
store i23 %0, i23* %2
23+
%3 = getelementptr inbounds %S, %S* %1, i64 0, i32 0, i32 1
24+
%4 = load i8, i8* %3
25+
ret i8 %4
26+
}
27+
28+
define i32 @bar(i16 %0) {
29+
; CHECK-LABEL: @bar(
30+
; CHECK-NEXT: Entry:
31+
; CHECK-NEXT: [[DOTSROA_0:%.*]] = alloca [3 x i8], align 8
32+
; CHECK-NEXT: [[DOTSROA_0_0__SROA_CAST2:%.*]] = bitcast [3 x i8]* [[DOTSROA_0]] to i16*
33+
; CHECK-NEXT: store i16 [[TMP0:%.*]], i16* [[DOTSROA_0_0__SROA_CAST2]], align 8
34+
; CHECK-NEXT: [[DOTSROA_0_0_Q_SROA_CAST1:%.*]] = bitcast [3 x i8]* [[DOTSROA_0]] to i17*
35+
; CHECK-NEXT: [[DOTSROA_0_0__SROA_0_0_:%.*]] = load i17, i17* [[DOTSROA_0_0_Q_SROA_CAST1]], align 8
36+
; CHECK-NEXT: [[TMP1:%.*]] = zext i17 [[DOTSROA_0_0__SROA_0_0_]] to i32
37+
; CHECK-NEXT: ret i32 [[TMP1]]
38+
;
39+
Entry:
40+
%1 = alloca %S
41+
%2 = bitcast %S* %1 to i16*
42+
store i16 %0, i16* %2
43+
%3 = getelementptr inbounds %S, %S* %1, i64 0, i32 0
44+
%q = bitcast [4 x i8]* %3 to i17*
45+
%4 = load i17, i17* %q
46+
%5 = zext i17 %4 to i32
47+
ret i32 %5
48+
}

0 commit comments

Comments
 (0)