Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / Transforms / IPO / WholeProgramDevirt.cpp
blob8fae05bef2ae1373e84d63172e430a333e27c762
1 //===- WholeProgramDevirt.cpp - Unit tests for whole-program devirt -------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "gtest/gtest.h"
13 using namespace llvm;
14 using namespace wholeprogramdevirt;
16 TEST(WholeProgramDevirt, findLowestOffset) {
17 VTableBits VT1;
18 VT1.ObjectSize = 8;
19 VT1.Before.BytesUsed = {1 << 0};
20 VT1.After.BytesUsed = {1 << 1};
22 VTableBits VT2;
23 VT2.ObjectSize = 8;
24 VT2.Before.BytesUsed = {1 << 1};
25 VT2.After.BytesUsed = {1 << 0};
27 TypeMemberInfo TM1{&VT1, 0};
28 TypeMemberInfo TM2{&VT2, 0};
29 VirtualCallTarget Targets[] = {
30 {&TM1, /*IsBigEndian=*/false},
31 {&TM2, /*IsBigEndian=*/false},
34 EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
35 EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
37 EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
38 EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
40 TM1.Offset = 4;
41 EXPECT_EQ(33ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
42 EXPECT_EQ(65ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
44 EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
45 EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
47 TM1.Offset = 8;
48 TM2.Offset = 8;
49 EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/false, 1));
50 EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/true, 1));
52 EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/false, 8));
53 EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/true, 8));
55 VT1.After.BytesUsed = {0xff, 0, 0, 0, 0xff};
56 VT2.After.BytesUsed = {0xff, 1, 0, 0, 0};
57 EXPECT_EQ(16ull, findLowestOffset(Targets, /*IsAfter=*/true, 16));
58 EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/true, 32));
61 TEST(WholeProgramDevirt, setReturnValues) {
62 VTableBits VT1;
63 VT1.ObjectSize = 8;
65 VTableBits VT2;
66 VT2.ObjectSize = 8;
68 TypeMemberInfo TM1{&VT1, 0};
69 TypeMemberInfo TM2{&VT2, 0};
70 VirtualCallTarget Targets[] = {
71 {&TM1, /*IsBigEndian=*/false},
72 {&TM2, /*IsBigEndian=*/false},
75 TM1.Offset = 4;
76 TM2.Offset = 4;
78 int64_t OffsetByte;
79 uint64_t OffsetBit;
81 Targets[0].RetVal = 1;
82 Targets[1].RetVal = 0;
83 setBeforeReturnValues(Targets, 32, 1, OffsetByte, OffsetBit);
84 EXPECT_EQ(-5ll, OffsetByte);
85 EXPECT_EQ(0ull, OffsetBit);
86 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes);
87 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.BytesUsed);
88 EXPECT_EQ(std::vector<uint8_t>{0}, VT2.Before.Bytes);
89 EXPECT_EQ(std::vector<uint8_t>{1}, VT2.Before.BytesUsed);
91 Targets[0].RetVal = 0;
92 Targets[1].RetVal = 1;
93 setBeforeReturnValues(Targets, 39, 1, OffsetByte, OffsetBit);
94 EXPECT_EQ(-5ll, OffsetByte);
95 EXPECT_EQ(7ull, OffsetBit);
96 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes);
97 EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.Before.BytesUsed);
98 EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.Before.Bytes);
99 EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.Before.BytesUsed);
101 Targets[0].RetVal = 12;
102 Targets[1].RetVal = 34;
103 setBeforeReturnValues(Targets, 40, 8, OffsetByte, OffsetBit);
104 EXPECT_EQ(-6ll, OffsetByte);
105 EXPECT_EQ(0ull, OffsetBit);
106 EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.Before.Bytes);
107 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.Before.BytesUsed);
108 EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.Before.Bytes);
109 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.Before.BytesUsed);
111 Targets[0].RetVal = 56;
112 Targets[1].RetVal = 78;
113 setBeforeReturnValues(Targets, 48, 16, OffsetByte, OffsetBit);
114 EXPECT_EQ(-8ll, OffsetByte);
115 EXPECT_EQ(0ull, OffsetBit);
116 EXPECT_EQ((std::vector<uint8_t>{1, 12, 0, 56}), VT1.Before.Bytes);
117 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
118 VT1.Before.BytesUsed);
119 EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 0, 78}), VT2.Before.Bytes);
120 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
121 VT2.Before.BytesUsed);
123 Targets[0].RetVal = 1;
124 Targets[1].RetVal = 0;
125 setAfterReturnValues(Targets, 32, 1, OffsetByte, OffsetBit);
126 EXPECT_EQ(4ll, OffsetByte);
127 EXPECT_EQ(0ull, OffsetBit);
128 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes);
129 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.BytesUsed);
130 EXPECT_EQ(std::vector<uint8_t>{0}, VT2.After.Bytes);
131 EXPECT_EQ(std::vector<uint8_t>{1}, VT2.After.BytesUsed);
133 Targets[0].RetVal = 0;
134 Targets[1].RetVal = 1;
135 setAfterReturnValues(Targets, 39, 1, OffsetByte, OffsetBit);
136 EXPECT_EQ(4ll, OffsetByte);
137 EXPECT_EQ(7ull, OffsetBit);
138 EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes);
139 EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.After.BytesUsed);
140 EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.After.Bytes);
141 EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.After.BytesUsed);
143 Targets[0].RetVal = 12;
144 Targets[1].RetVal = 34;
145 setAfterReturnValues(Targets, 40, 8, OffsetByte, OffsetBit);
146 EXPECT_EQ(5ll, OffsetByte);
147 EXPECT_EQ(0ull, OffsetBit);
148 EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.After.Bytes);
149 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.After.BytesUsed);
150 EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.After.Bytes);
151 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.After.BytesUsed);
153 Targets[0].RetVal = 56;
154 Targets[1].RetVal = 78;
155 setAfterReturnValues(Targets, 48, 16, OffsetByte, OffsetBit);
156 EXPECT_EQ(6ll, OffsetByte);
157 EXPECT_EQ(0ull, OffsetBit);
158 EXPECT_EQ((std::vector<uint8_t>{1, 12, 56, 0}), VT1.After.Bytes);
159 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
160 VT1.After.BytesUsed);
161 EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 78, 0}), VT2.After.Bytes);
162 EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}),
163 VT2.After.BytesUsed);