Skip to content

Commit ffdace4

Browse files
[SROA] Add new test cases to cover existing SROA behavior that structs will be scalarized.
Add an IR in unit test directory, which demonstrate the scalarization for struct allocations. This is added to pave the way for an SROA change to skip scalarization for some cases. Reviewed By: davidxl Differential Revision: https://reviews.llvm.org/D114128
1 parent 7eec832 commit ffdace4

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
; RUN: opt < %s -sroa -S | FileCheck %s
2+
; RUN: opt < %s -passes=sroa -S | FileCheck %s
3+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
%struct.RetValIntChar = type { i32, i8 }
7+
%struct.RetValTwoInts = type { i32, i32 }
8+
%struct.RetValOneIntTwoChar = type { i32, i8 }
9+
10+
; Tests that a struct of type {i32, i8} is scalarized by SROA.
11+
; FIXME: SROA should skip scalarization since there is no scalar access.
12+
; Currently scalarization happens due to the mismatch of allocated size
13+
; and the actual structure size.
14+
define i64 @test_struct_of_int_char(i1 zeroext %test, i64 ()* %p) {
15+
; CHECK-LABEL: @test_struct_of_int_char(
16+
; CHECK-NEXT: entry:
17+
; COM: Check that registers are used and alloca instructions are eliminated.
18+
; CHECK-NOT: alloca
19+
; CHECK: if.then:
20+
; CHECK-NEXT: br label [[RETURN:%.*]]
21+
; CHECK: if.end:
22+
; CHECK-NEXT: call i64 [[P:%.*]]()
23+
; CHECK: br label [[RETURN]]
24+
; CHECK: return:
25+
; COM: Check there are more than one PHI nodes to select scalarized values.
26+
; CHECK-COUNT-3: phi
27+
; CHECK: ret i64
28+
;
29+
entry:
30+
%retval = alloca %struct.RetValIntChar, align 4
31+
br i1 %test, label %if.then, label %if.end
32+
33+
if.then: ; preds = %entry
34+
%x = getelementptr inbounds %struct.RetValIntChar, %struct.RetValIntChar* %retval, i32 0, i32 0
35+
store i32 0, i32* %x, align 4
36+
%y = getelementptr inbounds %struct.RetValIntChar, %struct.RetValIntChar* %retval, i32 0, i32 1
37+
store i8 0, i8* %y, align 4
38+
br label %return
39+
40+
if.end: ; preds = %entry
41+
%call = call i64 %p()
42+
%0 = bitcast %struct.RetValIntChar* %retval to i64*
43+
store i64 %call, i64* %0, align 4
44+
br label %return
45+
46+
return: ; preds = %if.end, %if.then
47+
%1 = bitcast %struct.RetValIntChar* %retval to i64*
48+
%2 = load i64, i64* %1, align 4
49+
ret i64 %2
50+
}
51+
52+
; Test that the alloca of struct{int, int} will be scalarized by SROA.
53+
define i64 @test_struct_of_two_int(i1 zeroext %test, i64 ()* %p) {
54+
; CHECK-LABEL: @test_struct_of_two_int(
55+
; CHECK-NEXT: entry:
56+
; CHECK-NOT: alloca
57+
; CHECK: if.then:
58+
; CHECK-NEXT: br label [[RETURN:%.*]]
59+
; CHECK: if.end:
60+
; CHECK-NEXT: call i64
61+
; CHECK: return:
62+
; COM: Check that there are more than one PHI nodes to select the scalarized values.
63+
; CHECK-COUNT-2: phi
64+
; CHECK: ret i64
65+
;
66+
entry:
67+
%retval = alloca %struct.RetValTwoInts, align 4
68+
br i1 %test, label %if.then, label %if.end
69+
70+
if.then: ; preds = %entry
71+
%x = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 0
72+
store i32 0, i32* %x, align 4
73+
%y = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 1
74+
store i32 0, i32* %y, align 4
75+
br label %return
76+
77+
if.end: ; preds = %entry
78+
%call = call i64 %p()
79+
%0 = bitcast %struct.RetValTwoInts* %retval to i64*
80+
store i64 %call, i64* %0, align 4
81+
br label %return
82+
83+
return: ; preds = %if.end, %if.then
84+
%1 = bitcast %struct.RetValTwoInts* %retval to i64*
85+
%2 = load i64, i64* %1, align 4
86+
ret i64 %2
87+
}
88+
89+
; Tests that allocated struct type is scalarized when non-constant values are
90+
; stored into its fields.
91+
define i64 @test_one_field_has_runtime_value(i1 zeroext %test, i64 ()* %p) {
92+
; CHECK-LABEL: @test_one_field_has_runtime_value(
93+
; CHECK-NEXT: entry:
94+
; CHECK-NOT: alloca
95+
; CHECK: call void @srand
96+
; CHECK: if.then:
97+
; CHECK-NEXT: call i32 @rand()
98+
; CHECK-NEXT: br label
99+
; CHECK: if.end:
100+
; CHECK-NEXT: call i64
101+
; CHECK: return:
102+
; CHECK-COUNT-2: phi i32
103+
; CHECK: ret i64
104+
;
105+
entry:
106+
%retval = alloca %struct.RetValTwoInts, align 4
107+
%call = call i64 @time(i64* null)
108+
%conv = trunc i64 %call to i32
109+
call void @srand(i32 %conv)
110+
br i1 %test, label %if.then, label %if.end
111+
112+
if.then: ; preds = %entry
113+
%x = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 0
114+
%call1 = call i32 @rand()
115+
store i32 %call1, i32* %x, align 4
116+
%y = getelementptr inbounds %struct.RetValTwoInts, %struct.RetValTwoInts* %retval, i32 0, i32 1
117+
store i32 1, i32* %y, align 4
118+
br label %return
119+
120+
if.end: ; preds = %entry
121+
%call2 = call i64 %p()
122+
%0 = bitcast %struct.RetValTwoInts* %retval to i64*
123+
store i64 %call2, i64* %0, align 4
124+
br label %return
125+
126+
return: ; preds = %if.end, %if.then
127+
%1 = bitcast %struct.RetValTwoInts* %retval to i64*
128+
%2 = load i64, i64* %1, align 4
129+
ret i64 %2
130+
}
131+
132+
; Function Attrs: nounwind
133+
declare void @srand(i32)
134+
135+
; Function Attrs: nounwind
136+
declare i64 @time(i64*)
137+
138+
; Function Attrs: nounwind
139+
declare i32 @rand()

0 commit comments

Comments
 (0)