xref: /llvm-project/polly/test/ScopInfo/multiple-types-non-power-of-two.ll (revision e1f056f692d869708c1898d9d65a69ac5584a0ed)
1; RUN: opt %loadNPMPolly '-passes=print<polly-function-scops>' -polly-allow-differing-element-types -disable-output < %s 2>&1 | FileCheck %s
2;
3;  void multiple_types(i8 *A) {
4;    for (long i = 0; i < 100; i++) {
5;      A[i] = *(i1 *)&A[1 * i] +
6;             *(i16 *)&A[2 * i] +
7;             *(i24 *)&A[4 * i] +
8;             *(i32 *)&A[4 * i] +
9;             *(i40 *)&A[8 * i] +
10;             *(i48 *)&A[8 * i] +
11;             *(i56 *)&A[8 * i] +
12;             *(i64 *)&A[8 * i] +
13;             *(i120 *)&A[16 * i] +
14;             *(i192 *)&A[24 * i] +
15;             *(i248 *)&A[32 * i];
16;    }
17;  }
18;
19; Verify that different data type sizes are correctly modeled. Specifically,
20; we want to verify that type i1 is modeled with allocation size i8,
21; type i24 is modeled with allocation size i32 and that i40, i48 and i56 are
22; modeled with allocation size i64. Larger types, e.g., i120, i192 and i248 are
23; not rounded up to the next power-of-two allocation size, but rather to the
24; next multiple of 64.
25
26; The allocation size discussed above defines the number of canonical array
27; elements accessed. For example, even though i24 only consists of 3 bytes,
28; its allocation size is 4 bytes. Consequently, we model the access to an
29; i24 element as an access to four canonical elements resulting in access
30; relation constraints '4i0 <= o0 <= 3 + 4i0' instead of '3i0 <= o0 <= 2 + 3i0'.
31
32; CHECK: Statements {
33; CHECK:   Stmt_bb2
34; CHECK:         Domain :=
35; CHECK:             { Stmt_bb2[i0] : 0 <= i0 <= 99 };
36; CHECK:         Schedule :=
37; CHECK:             { Stmt_bb2[i0] -> [i0] };
38; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
39; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 2i0 <= o0 <= 1 + 2i0 };
40; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
41; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 4i0 <= o0 <= 3 + 4i0 };
42; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
43; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 4i0 <= o0 <= 3 + 4i0 };
44; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
45; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 8i0 <= o0 <= 7 + 8i0 };
46; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
47; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 8i0 <= o0 <= 7 + 8i0 };
48; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
49; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 8i0 <= o0 <= 7 + 8i0 };
50; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
51; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 8i0 <= o0 <= 7 + 8i0 };
52; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
53; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 16i0 <= o0 <= 15 + 16i0 };
54; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
55; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 24i0 <= o0 <= 23 + 24i0 };
56; CHECK:         ReadAccess :=       [Reduction Type: NONE] [Scalar: 0]
57; CHECK:             { Stmt_bb2[i0] -> MemRef_A[o0] : 32i0 <= o0 <= 31 + 32i0 };
58; CHECK:         MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 0]
59; CHECK:             { Stmt_bb2[i0] -> MemRef_A[i0] };
60; CHECK: }
61
62target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
63
64define void @multiple_types(ptr %A) {
65bb:
66  br label %bb1
67
68bb1:                                              ; preds = %bb20, %bb
69  %i.0 = phi i64 [ 0, %bb ], [ %tmp21, %bb20 ]
70  %exitcond = icmp ne i64 %i.0, 100
71  br i1 %exitcond, label %bb2, label %bb22
72
73bb2:                                              ; preds = %bb1
74  %load.i1.offset = mul i64 %i.0, 1
75  %load.i1.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i1.offset
76  %load.i1.val = load i1, ptr %load.i1.ptr
77  %load.i1.val.trunc = zext i1 %load.i1.val to i8
78
79  %load.i16.offset = mul i64 %i.0, 2
80  %load.i16.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i16.offset
81  %load.i16.val = load i16, ptr %load.i16.ptr
82  %load.i16.val.trunc = trunc i16 %load.i16.val to i8
83
84  %load.i24.offset = mul i64 %i.0, 4
85  %load.i24.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i24.offset
86  %load.i24.val = load i24, ptr %load.i24.ptr
87  %load.i24.val.trunc = trunc i24 %load.i24.val to i8
88
89  %load.i32.offset = mul i64 %i.0, 4
90  %load.i32.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i32.offset
91  %load.i32.val = load i32, ptr %load.i32.ptr
92  %load.i32.val.trunc = trunc i32 %load.i32.val to i8
93
94  %load.i40.offset = mul i64 %i.0, 8
95  %load.i40.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i40.offset
96  %load.i40.val = load i40, ptr %load.i40.ptr
97  %load.i40.val.trunc = trunc i40 %load.i40.val to i8
98
99  %load.i48.offset = mul i64 %i.0, 8
100  %load.i48.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i48.offset
101  %load.i48.val = load i48, ptr %load.i48.ptr
102  %load.i48.val.trunc = trunc i48 %load.i48.val to i8
103
104  %load.i56.offset = mul i64 %i.0, 8
105  %load.i56.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i56.offset
106  %load.i56.val = load i56, ptr %load.i56.ptr
107  %load.i56.val.trunc = trunc i56 %load.i56.val to i8
108
109  %load.i64.offset = mul i64 %i.0, 8
110  %load.i64.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i64.offset
111  %load.i64.val = load i64, ptr %load.i64.ptr
112  %load.i64.val.trunc = trunc i64 %load.i64.val to i8
113
114  %load.i120.offset = mul i64 %i.0, 16
115  %load.i120.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i120.offset
116  %load.i120.val = load i120, ptr %load.i120.ptr
117  %load.i120.val.trunc = trunc i120 %load.i120.val to i8
118
119  %load.i192.offset = mul i64 %i.0, 24
120  %load.i192.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i192.offset
121  %load.i192.val = load i192, ptr %load.i192.ptr
122  %load.i192.val.trunc = trunc i192 %load.i192.val to i8
123
124  %load.i248.offset = mul i64 %i.0, 32
125  %load.i248.ptr = getelementptr inbounds i8, ptr %A, i64 %load.i248.offset
126  %load.i248.val = load i248, ptr %load.i248.ptr
127  %load.i248.val.trunc = trunc i248 %load.i248.val to i8
128
129  %sum = add i8 %load.i1.val.trunc, %load.i16.val.trunc
130  %sum0 = add i8 %sum, %load.i24.val.trunc
131  %sum1 = add i8 %sum0, %load.i32.val.trunc
132  %sum2 = add i8 %sum1, %load.i40.val.trunc
133  %sum3 = add i8 %sum2, %load.i48.val.trunc
134  %sum4 = add i8 %sum3, %load.i56.val.trunc
135  %sum5 = add i8 %sum4, %load.i64.val.trunc
136  %sum6 = add i8 %sum5, %load.i120.val.trunc
137  %sum7 = add i8 %sum6, %load.i192.val.trunc
138  %sum8 = add i8 %sum7, %load.i248.val.trunc
139  %tmp7 = getelementptr inbounds i8, ptr %A, i64 %i.0
140  store i8 %sum8, ptr %tmp7
141  br label %bb20
142
143bb20:                                             ; preds = %bb2
144  %tmp21 = add nuw nsw i64 %i.0, 1
145  br label %bb1
146
147bb22:                                             ; preds = %bb1
148  ret void
149}
150