1 //===- TestStackOffset.cpp - StackOffset unit tests------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "AArch64StackOffset.h"
10 #include "gtest/gtest.h"
14 TEST(StackOffset
, MixedSize
) {
15 StackOffset
A(1, MVT::i8
);
16 EXPECT_EQ(1, A
.getBytes());
18 StackOffset
B(2, MVT::i32
);
19 EXPECT_EQ(8, B
.getBytes());
21 StackOffset
C(2, MVT::v4i64
);
22 EXPECT_EQ(64, C
.getBytes());
24 StackOffset
D(2, MVT::nxv4i64
);
25 EXPECT_EQ(64, D
.getScalableBytes());
27 StackOffset
E(2, MVT::v4i64
);
28 EXPECT_EQ(0, E
.getScalableBytes());
30 StackOffset
F(2, MVT::nxv4i64
);
31 EXPECT_EQ(0, F
.getBytes());
34 TEST(StackOffset
, Add
) {
35 StackOffset
A(1, MVT::i64
);
36 StackOffset
B(1, MVT::i32
);
37 StackOffset C
= A
+ B
;
38 EXPECT_EQ(12, C
.getBytes());
40 StackOffset
D(1, MVT::i32
);
42 EXPECT_EQ(12, D
.getBytes());
44 StackOffset
E(1, MVT::nxv1i32
);
45 StackOffset F
= C
+ E
;
46 EXPECT_EQ(12, F
.getBytes());
47 EXPECT_EQ(4, F
.getScalableBytes());
50 TEST(StackOffset
, Sub
) {
51 StackOffset
A(1, MVT::i64
);
52 StackOffset
B(1, MVT::i32
);
53 StackOffset C
= A
- B
;
54 EXPECT_EQ(4, C
.getBytes());
56 StackOffset
D(1, MVT::i64
);
58 EXPECT_EQ(0, D
.getBytes());
60 C
+= StackOffset(2, MVT::nxv1i32
);
61 StackOffset E
= StackOffset(1, MVT::nxv1i32
);
62 StackOffset F
= C
- E
;
63 EXPECT_EQ(4, F
.getBytes());
64 EXPECT_EQ(4, F
.getScalableBytes());
67 TEST(StackOffset
, isZero
) {
68 StackOffset
A(0, MVT::i64
);
69 StackOffset
B(0, MVT::i32
);
71 EXPECT_TRUE(!(A
+ B
));
73 StackOffset
C(0, MVT::nxv1i32
);
74 EXPECT_TRUE(!(A
+ C
));
76 StackOffset
D(1, MVT::nxv1i32
);
77 EXPECT_FALSE(!(A
+ D
));
80 TEST(StackOffset
, isValid
) {
81 EXPECT_FALSE(StackOffset(1, MVT::nxv8i1
).isValid());
82 EXPECT_TRUE(StackOffset(2, MVT::nxv8i1
).isValid());
85 #ifdef GTEST_HAS_DEATH_TEST
86 EXPECT_DEATH(StackOffset(1, MVT::i1
),
87 "Offset type is not a multiple of bytes");
88 EXPECT_DEATH(StackOffset(1, MVT::nxv1i1
),
89 "Offset type is not a multiple of bytes");
90 #endif // defined GTEST_HAS_DEATH_TEST
91 #endif // not defined NDEBUG
94 TEST(StackOffset
, getForFrameOffset
) {
95 StackOffset
A(1, MVT::i64
);
96 StackOffset
B(1, MVT::i32
);
97 StackOffset
C(1, MVT::nxv4i32
);
99 // If all offsets can be materialized with only ADDVL,
100 // make sure PLSized is 0.
101 int64_t ByteSized
, VLSized
, PLSized
;
102 (A
+ B
+ C
).getForFrameOffset(ByteSized
, PLSized
, VLSized
);
103 EXPECT_EQ(12, ByteSized
);
104 EXPECT_EQ(1, VLSized
);
105 EXPECT_EQ(0, PLSized
);
107 // If we need an ADDPL to materialize the offset, and the number of scalable
108 // bytes fits the ADDPL immediate, fold the scalable bytes to fit in PLSized.
109 StackOffset
D(1, MVT::nxv16i1
);
110 (C
+ D
).getForFrameOffset(ByteSized
, PLSized
, VLSized
);
111 EXPECT_EQ(0, ByteSized
);
112 EXPECT_EQ(0, VLSized
);
113 EXPECT_EQ(9, PLSized
);
115 StackOffset
E(4, MVT::nxv4i32
);
116 StackOffset
F(1, MVT::nxv16i1
);
117 (E
+ F
).getForFrameOffset(ByteSized
, PLSized
, VLSized
);
118 EXPECT_EQ(0, ByteSized
);
119 EXPECT_EQ(0, VLSized
);
120 EXPECT_EQ(33, PLSized
);
122 // If the offset requires an ADDPL instruction to materialize, and would
123 // require more than two instructions, decompose it into both
124 // ADDVL (n x 16 bytes) and ADDPL (n x 2 bytes) instructions.
125 StackOffset
G(8, MVT::nxv4i32
);
126 StackOffset
H(1, MVT::nxv16i1
);
127 (G
+ H
).getForFrameOffset(ByteSized
, PLSized
, VLSized
);
128 EXPECT_EQ(0, ByteSized
);
129 EXPECT_EQ(8, VLSized
);
130 EXPECT_EQ(1, PLSized
);