xref: /llvm-project/llvm/test/Transforms/InferAlignment/vector.ll (revision 0f152a55d3e4e71f7c795bf555e40c8895b97077)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s
3
4; InferAlignment should be able to prove vector alignment in the
5; presence of a few mild address computation tricks.
6
7; ------------------------------------------------------------------------------
8; alloca
9; ------------------------------------------------------------------------------
10
11define void @alloca(<2 x i64> %y) {
12; CHECK-LABEL: define void @alloca
13; CHECK-SAME: (<2 x i64> [[Y:%.*]]) {
14; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca <2 x i64>, align 16
15; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i64>, ptr [[ALLOCA]], align 16
16; CHECK-NEXT:    store <2 x i64> [[Y]], ptr [[ALLOCA]], align 16
17; CHECK-NEXT:    ret void
18;
19  %alloca = alloca <2 x i64>
20  %load = load <2 x i64>, ptr %alloca, align 1
21  store <2 x i64> %y, ptr %alloca, align 1
22  ret void
23}
24
25; ------------------------------------------------------------------------------
26; global
27; ------------------------------------------------------------------------------
28
29@x.vector = external global <2 x i64>, align 16
30
31define void @global(<2 x i64> %y) {
32; CHECK-LABEL: define void @global
33; CHECK-SAME: (<2 x i64> [[Y:%.*]]) {
34; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i64>, ptr @x.vector, align 16
35; CHECK-NEXT:    store <2 x i64> [[Y]], ptr @x.vector, align 16
36; CHECK-NEXT:    ret void
37;
38  %load = load <2 x i64>, ptr @x.vector, align 1
39  store <2 x i64> %y, ptr @x.vector, align 1
40  ret void
41}
42
43; ------------------------------------------------------------------------------
44; getelementptr
45; ------------------------------------------------------------------------------
46
47@vector = external global <2 x i64>, align 16
48@vector.arr = external global [13 x <2 x i64>], align 16
49
50; ------------------------------------------------------------------------------
51; 1d access
52; ------------------------------------------------------------------------------
53
54define void @vector_singular(i32 %i, <2 x i64> %y) {
55; CHECK-LABEL: define void @vector_singular
56; CHECK-SAME: (i32 [[I:%.*]], <2 x i64> [[Y:%.*]]) {
57; CHECK-NEXT:    [[GEP:%.*]] = getelementptr <2 x i64>, ptr @vector, i32 [[I]]
58; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i64>, ptr [[GEP]], align 16
59; CHECK-NEXT:    store <2 x i64> [[Y]], ptr [[GEP]], align 16
60; CHECK-NEXT:    ret void
61;
62  %gep = getelementptr <2 x i64>, ptr @vector, i32 %i
63  %load = load <2 x i64>, ptr %gep, align 1
64  store <2 x i64> %y, ptr %gep, align 1
65  ret void
66}
67
68; ------------------------------------------------------------------------------
69; 2d access
70; ------------------------------------------------------------------------------
71
72define void @vector_array(i32 %i, i32 %j, <2 x i64> %y) {
73; CHECK-LABEL: define void @vector_array
74; CHECK-SAME: (i32 [[I:%.*]], i32 [[J:%.*]], <2 x i64> [[Y:%.*]]) {
75; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [13 x <2 x i64>], ptr @vector.arr, i32 [[I]], i32 [[J]]
76; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i64>, ptr [[GEP]], align 16
77; CHECK-NEXT:    store <2 x i64> [[Y]], ptr [[GEP]], align 16
78; CHECK-NEXT:    ret void
79;
80  %gep = getelementptr [13 x <2 x i64>], ptr @vector.arr, i32 %i, i32 %j
81  %load = load <2 x i64>, ptr %gep, align 1
82  store <2 x i64> %y, ptr %gep, align 1
83  ret void
84}
85
86; ------------------------------------------------------------------------------
87; non-vector array type
88; ------------------------------------------------------------------------------
89
90; When we see a unaligned load or store from an insufficiently aligned global or
91; alloca, increase the alignment, turning it into an aligned load or store.
92@x.array = internal global [4 x i32] zeroinitializer
93
94define void @nonvector_array() {
95; CHECK-LABEL: define void @nonvector_array() {
96; CHECK-NEXT:    [[LOAD_0:%.*]] = load <16 x i8>, ptr @x.array, align 16
97; CHECK-NEXT:    store <16 x i8> zeroinitializer, ptr @x.array, align 16
98; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i32], ptr @x.array, i16 0, i16 2
99; CHECK-NEXT:    [[LOAD_1:%.*]] = load <16 x i8>, ptr [[GEP]], align 8
100; CHECK-NEXT:    store <16 x i8> zeroinitializer, ptr [[GEP]], align 8
101; CHECK-NEXT:    ret void
102;
103  %load.0 = load <16 x i8>, ptr @x.array, align 1
104  store <16 x i8> zeroinitializer, ptr @x.array, align 1
105
106  %gep = getelementptr [4 x i32], ptr @x.array, i16 0, i16 2
107  %load.1 = load <16 x i8>, ptr %gep, align 1
108  store <16 x i8> zeroinitializer, ptr %gep, align 1
109
110  ret void
111}
112