1//===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
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//===----------------------------------------------------------------------===//
8
9#include "llvm/Analysis/MemoryLocation.h"
10#include "llvm/Analysis/OptimizationRemarkEmitter.h"
11#include "llvm/AsmParser/Parser.h"
12#include "llvm/CodeGen/MachineModuleInfo.h"
13#include "llvm/CodeGen/SelectionDAG.h"
14#include "llvm/CodeGen/TargetLowering.h"
15#include "llvm/IR/MDBuilder.h"
16#include "llvm/MC/TargetRegistry.h"
17#include "llvm/Support/KnownBits.h"
18#include "llvm/Support/SourceMgr.h"
19#include "llvm/Support/TargetSelect.h"
20#include "llvm/Target/TargetMachine.h"
21#include "gtest/gtest.h"
22
23namespace llvm {
24
25class AArch64SelectionDAGTest : public testing::Test {
26protected:
27 static void SetUpTestCase() {
28 InitializeAllTargets();
29 InitializeAllTargetMCs();
30 }
31
32 void SetUp() override {
33 StringRef Assembly = "define void @f() { ret void }";
34
35 Triple TargetTriple("aarch64--");
36 std::string Error;
37 const Target *T = TargetRegistry::lookupTarget(ArchName: "", TheTriple&: TargetTriple, Error);
38 // FIXME: These tests do not depend on AArch64 specifically, but we have to
39 // initialize a target. A skeleton Target for unittests would allow us to
40 // always run these tests.
41 if (!T)
42 GTEST_SKIP();
43
44 TargetOptions Options;
45 TM = std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
46 T->createTargetMachine(TT: "AArch64", CPU: "", Features: "+sve", Options, RM: std::nullopt,
47 CM: std::nullopt, OL: CodeGenOptLevel::Aggressive)));
48 if (!TM)
49 GTEST_SKIP();
50
51 SMDiagnostic SMError;
52 M = parseAssemblyString(AsmString: Assembly, Err&: SMError, Context);
53 if (!M)
54 report_fatal_error(reason: SMError.getMessage());
55 M->setDataLayout(TM->createDataLayout());
56
57 F = M->getFunction(Name: "f");
58 if (!F)
59 report_fatal_error(reason: "F?");
60
61 MachineModuleInfo MMI(TM.get());
62
63 MF = std::make_unique<MachineFunction>(args&: *F, args&: *TM, args: *TM->getSubtargetImpl(*F), args: 0,
64 args&: MMI);
65
66 DAG = std::make_unique<SelectionDAG>(args&: *TM, args: CodeGenOptLevel::None);
67 if (!DAG)
68 report_fatal_error(reason: "DAG?");
69 OptimizationRemarkEmitter ORE(F);
70 DAG->init(NewMF&: *MF, NewORE&: ORE, PassPtr: nullptr, LibraryInfo: nullptr, UA: nullptr, PSIin: nullptr, BFIin: nullptr, FnVarLocs: nullptr);
71 }
72
73 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {
74 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);
75 }
76
77 EVT getTypeToTransformTo(EVT VT) {
78 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);
79 }
80
81 LLVMContext Context;
82 std::unique_ptr<LLVMTargetMachine> TM;
83 std::unique_ptr<Module> M;
84 Function *F;
85 std::unique_ptr<MachineFunction> MF;
86 std::unique_ptr<SelectionDAG> DAG;
87};
88
89TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {
90 SDLoc Loc;
91 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
92 auto Int16VT = EVT::getIntegerVT(Context, BitWidth: 16);
93 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4);
94 auto OutVecVT = EVT::getVectorVT(Context, VT: Int16VT, NumElements: 2);
95 auto InVec = DAG->getConstant(Val: 0, DL: Loc, VT: InVecVT);
96 auto Op = DAG->getNode(Opcode: ISD::ZERO_EXTEND_VECTOR_INREG, DL: Loc, VT: OutVecVT, Operand: InVec);
97 auto DemandedElts = APInt(2, 3);
98 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
99 EXPECT_TRUE(Known.isZero());
100}
101
102TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {
103 SDLoc Loc;
104 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
105 auto Int16VT = EVT::getIntegerVT(Context, BitWidth: 16);
106 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, IsScalable: true);
107 auto OutVecVT = EVT::getVectorVT(Context, VT: Int16VT, NumElements: 2, IsScalable: true);
108 auto InVec = DAG->getConstant(Val: 0, DL: Loc, VT: InVecVT);
109 auto Op = DAG->getNode(Opcode: ISD::ZERO_EXTEND_VECTOR_INREG, DL: Loc, VT: OutVecVT, Operand: InVec);
110 auto DemandedElts = APInt(2, 3);
111 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
112
113 // We don't know anything for SVE at the moment.
114 EXPECT_EQ(Known.Zero, APInt(16, 0u));
115 EXPECT_EQ(Known.One, APInt(16, 0u));
116 EXPECT_FALSE(Known.isZero());
117}
118
119TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {
120 SDLoc Loc;
121 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
122 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 3);
123 auto IdxVT = EVT::getIntegerVT(Context, BitWidth: 64);
124 auto Vec = DAG->getConstant(Val: 0, DL: Loc, VT: VecVT);
125 auto ZeroIdx = DAG->getConstant(Val: 0, DL: Loc, VT: IdxVT);
126 auto Op = DAG->getNode(Opcode: ISD::EXTRACT_SUBVECTOR, DL: Loc, VT: VecVT, N1: Vec, N2: ZeroIdx);
127 auto DemandedElts = APInt(3, 7);
128 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);
129 EXPECT_TRUE(Known.isZero());
130}
131
132TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {
133 SDLoc Loc;
134 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
135 auto Int16VT = EVT::getIntegerVT(Context, BitWidth: 16);
136 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4);
137 auto OutVecVT = EVT::getVectorVT(Context, VT: Int16VT, NumElements: 2);
138 auto InVec = DAG->getConstant(Val: 1, DL: Loc, VT: InVecVT);
139 auto Op = DAG->getNode(Opcode: ISD::SIGN_EXTEND_VECTOR_INREG, DL: Loc, VT: OutVecVT, Operand: InVec);
140 auto DemandedElts = APInt(2, 3);
141 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);
142}
143
144TEST_F(AArch64SelectionDAGTest, ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {
145 SDLoc Loc;
146 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
147 auto Int16VT = EVT::getIntegerVT(Context, BitWidth: 16);
148 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 4, /*IsScalable=*/true);
149 auto OutVecVT = EVT::getVectorVT(Context, VT: Int16VT, NumElements: 2, /*IsScalable=*/true);
150 auto InVec = DAG->getConstant(Val: 1, DL: Loc, VT: InVecVT);
151 auto Op = DAG->getNode(Opcode: ISD::SIGN_EXTEND_VECTOR_INREG, DL: Loc, VT: OutVecVT, Operand: InVec);
152 auto DemandedElts = APInt(2, 3);
153 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);
154}
155
156TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {
157 SDLoc Loc;
158 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
159 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 3);
160 auto IdxVT = EVT::getIntegerVT(Context, BitWidth: 64);
161 auto Vec = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
162 auto ZeroIdx = DAG->getConstant(Val: 0, DL: Loc, VT: IdxVT);
163 auto Op = DAG->getNode(Opcode: ISD::EXTRACT_SUBVECTOR, DL: Loc, VT: VecVT, N1: Vec, N2: ZeroIdx);
164 auto DemandedElts = APInt(3, 7);
165 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);
166}
167
168TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {
169 TargetLowering TL(*TM);
170
171 SDLoc Loc;
172 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
173 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 3);
174 auto IdxVT = EVT::getIntegerVT(Context, BitWidth: 64);
175 auto Vec = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
176 auto ZeroIdx = DAG->getConstant(Val: 0, DL: Loc, VT: IdxVT);
177 auto Op = DAG->getNode(Opcode: ISD::EXTRACT_SUBVECTOR, DL: Loc, VT: VecVT, N1: Vec, N2: ZeroIdx);
178 auto DemandedElts = APInt(3, 7);
179 auto KnownUndef = APInt(3, 0);
180 auto KnownZero = APInt(3, 0);
181 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
182 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,
183 KnownZero, TLO),
184 false);
185}
186
187TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {
188 TargetLowering TL(*TM);
189
190 SDLoc Loc;
191 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
192 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 16);
193 SDValue UnknownOp = DAG->getRegister(Reg: 0, VT: InVecVT);
194 SDValue Mask1S = DAG->getConstant(Val: 0x8A, DL: Loc, VT: Int8VT);
195 SDValue Mask1V = DAG->getSplatBuildVector(VT: InVecVT, DL: Loc, Op: Mask1S);
196 SDValue N0 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: InVecVT, N1: Mask1V, N2: UnknownOp);
197
198 SDValue Mask2S = DAG->getConstant(Val: 0x55, DL: Loc, VT: Int8VT);
199 SDValue Mask2V = DAG->getSplatBuildVector(VT: InVecVT, DL: Loc, Op: Mask2S);
200
201 SDValue Op = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: InVecVT, N1: N0, N2: Mask2V);
202 // N0 = ?000?0?0
203 // Mask2V = 01010101
204 // =>
205 // Known.Zero = 00100000 (0xAA)
206 KnownBits Known;
207 APInt DemandedBits = APInt(8, 0xFF);
208 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
209 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
210 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
211}
212
213TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {
214 TargetLowering TL(*TM);
215
216 SDLoc Loc;
217 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
218 auto InVecVT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 16, /*IsScalable=*/true);
219 SDValue UnknownOp = DAG->getRegister(Reg: 0, VT: InVecVT);
220 SDValue Mask1S = DAG->getConstant(Val: 0x8A, DL: Loc, VT: Int8VT);
221 SDValue Mask1V = DAG->getSplatVector(VT: InVecVT, DL: Loc, Op: Mask1S);
222 SDValue N0 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: InVecVT, N1: Mask1V, N2: UnknownOp);
223
224 SDValue Mask2S = DAG->getConstant(Val: 0x55, DL: Loc, VT: Int8VT);
225 SDValue Mask2V = DAG->getSplatVector(VT: InVecVT, DL: Loc, Op: Mask2S);
226
227 SDValue Op = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: InVecVT, N1: N0, N2: Mask2V);
228
229 // N0 = ?000?0?0
230 // Mask2V = 01010101
231 // =>
232 // Known.Zero = 00100000 (0xAA)
233 KnownBits Known;
234 APInt DemandedBits = APInt(8, 0xFF);
235 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);
236 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));
237 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));
238}
239
240// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
241TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {
242 SDLoc Loc;
243 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
244 auto UnknownOp = DAG->getRegister(Reg: 0, VT: IntVT);
245 auto Mask = DAG->getConstant(Val: 0x8A, DL: Loc, VT: IntVT);
246 auto N0 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: IntVT, N1: Mask, N2: UnknownOp);
247 auto N1 = DAG->getConstant(Val: 0x55, DL: Loc, VT: IntVT);
248 auto Op = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: IntVT, N1: N0, N2: N1);
249 // N0 = ?000?0?0
250 // N1 = 01010101
251 // =>
252 // Known.One = 01010101 (0x55)
253 // Known.Zero = 00100000 (0x20)
254 KnownBits Known = DAG->computeKnownBits(Op);
255 EXPECT_EQ(Known.Zero, APInt(8, 0x20));
256 EXPECT_EQ(Known.One, APInt(8, 0x55));
257}
258
259// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
260TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {
261 SDLoc Loc;
262 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
263 auto UnknownOp = DAG->getRegister(Reg: 0, VT: IntVT);
264 auto Mask_Zero = DAG->getConstant(Val: 0x28, DL: Loc, VT: IntVT);
265 auto Mask_One = DAG->getConstant(Val: 0x20, DL: Loc, VT: IntVT);
266 auto N0 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: IntVT, N1: Mask_Zero, N2: UnknownOp);
267 N0 = DAG->getNode(Opcode: ISD::OR, DL: Loc, VT: IntVT, N1: Mask_One, N2: N0);
268 auto N1 = DAG->getConstant(Val: 0x65, DL: Loc, VT: IntVT);
269
270 KnownBits Known;
271
272 auto UnknownBorrow = DAG->getRegister(Reg: 1, VT: IntVT);
273 auto OpUnknownBorrow =
274 DAG->getNode(Opcode: ISD::UADDO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: UnknownBorrow);
275 // N0 = 0010?000
276 // N1 = 01100101
277 // B = ?
278 // =>
279 // Known.Zero = 01110000 (0x70)
280 // Known.One = 10000100 (0x84)
281 Known = DAG->computeKnownBits(Op: OpUnknownBorrow);
282 EXPECT_EQ(Known.Zero, APInt(8, 0x70));
283 EXPECT_EQ(Known.One, APInt(8, 0x84));
284
285 auto ZeroBorrow = DAG->getConstant(Val: 0x0, DL: Loc, VT: IntVT);
286 auto OpZeroBorrow =
287 DAG->getNode(Opcode: ISD::UADDO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: ZeroBorrow);
288 // N0 = 0010?000
289 // N1 = 01100101
290 // B = 0
291 // =>
292 // Known.Zero = 01110010 (0x72)
293 // Known.One = 10000101 (0x85)
294 Known = DAG->computeKnownBits(Op: OpZeroBorrow);
295 EXPECT_EQ(Known.Zero, APInt(8, 0x72));
296 EXPECT_EQ(Known.One, APInt(8, 0x85));
297
298 auto OneBorrow = DAG->getConstant(Val: 0x1, DL: Loc, VT: IntVT);
299 auto OpOneBorrow =
300 DAG->getNode(Opcode: ISD::UADDO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: OneBorrow);
301 // N0 = 0010?000
302 // N1 = 01100101
303 // B = 1
304 // =>
305 // Known.Zero = 01110001 (0x71)
306 // Known.One = 10000110 (0x86)
307 Known = DAG->computeKnownBits(Op: OpOneBorrow);
308 EXPECT_EQ(Known.Zero, APInt(8, 0x71));
309 EXPECT_EQ(Known.One, APInt(8, 0x86));
310}
311
312// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
313TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
314 SDLoc Loc;
315 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
316 auto N0 = DAG->getConstant(Val: 0x55, DL: Loc, VT: IntVT);
317 auto UnknownOp = DAG->getRegister(Reg: 0, VT: IntVT);
318 auto Mask = DAG->getConstant(Val: 0x2e, DL: Loc, VT: IntVT);
319 auto N1 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: IntVT, N1: Mask, N2: UnknownOp);
320 auto Op = DAG->getNode(Opcode: ISD::SUB, DL: Loc, VT: IntVT, N1: N0, N2: N1);
321 // N0 = 01010101
322 // N1 = 00?0???0
323 // =>
324 // Known.One = 00000001 (0x1)
325 // Known.Zero = 10000000 (0x80)
326 KnownBits Known = DAG->computeKnownBits(Op);
327 EXPECT_EQ(Known.Zero, APInt(8, 0x80));
328 EXPECT_EQ(Known.One, APInt(8, 0x1));
329}
330
331// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
332TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
333 SDLoc Loc;
334 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
335 auto N0 = DAG->getConstant(Val: 0x5a, DL: Loc, VT: IntVT);
336 auto UnknownOp = DAG->getRegister(Reg: 0, VT: IntVT); // ????????
337 auto Mask1_Zero = DAG->getConstant(Val: 0x8, DL: Loc, VT: IntVT); // 00001000
338 auto Mask1_One = DAG->getConstant(Val: 0x20, DL: Loc, VT: IntVT); // 00100000
339 // N1 = (???????? & 00001000) | 00100000 = 0010?000
340 auto N1 = DAG->getNode(Opcode: ISD::AND, DL: Loc, VT: IntVT, N1: Mask1_Zero, N2: UnknownOp);
341 N1 = DAG->getNode(Opcode: ISD::OR, DL: Loc, VT: IntVT, N1: Mask1_One, N2: N1);
342
343 KnownBits Known;
344
345 auto UnknownBorrow = DAG->getRegister(Reg: 1, VT: IntVT);
346 auto OpUnknownBorrow =
347 DAG->getNode(Opcode: ISD::USUBO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: UnknownBorrow);
348 // N0 = 01011010
349 // N1 = 0010?000
350 // B = ?
351 // =>
352 // Known.Zero = 11000100 (0xc4)
353 // Known.One = 00110000 (0x30)
354 Known = DAG->computeKnownBits(Op: OpUnknownBorrow);
355 EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
356 EXPECT_EQ(Known.One, APInt(8, 0x30));
357
358 auto ZeroBorrow = DAG->getConstant(Val: 0x0, DL: Loc, VT: IntVT);
359 auto OpZeroBorrow =
360 DAG->getNode(Opcode: ISD::USUBO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: ZeroBorrow);
361 // N0 = 01011010
362 // N1 = 0010?000
363 // B = 0
364 // =>
365 // Known.Zero = 11000101 (0xc5)
366 // Known.One = 00110010 (0x32)
367 Known = DAG->computeKnownBits(Op: OpZeroBorrow);
368 EXPECT_EQ(Known.Zero, APInt(8, 0xc5));
369 EXPECT_EQ(Known.One, APInt(8, 0x32));
370
371 auto OneBorrow = DAG->getConstant(Val: 0x1, DL: Loc, VT: IntVT);
372 auto OpOneBorrow =
373 DAG->getNode(Opcode: ISD::USUBO_CARRY, DL: Loc, VT: IntVT, N1: N0, N2: N1, N3: OneBorrow);
374 // N0 = 01011010
375 // N1 = 0010?000
376 // B = 1
377 // =>
378 // Known.Zero = 11000110 (0xc6)
379 // Known.One = 00110001 (0x31)
380 Known = DAG->computeKnownBits(Op: OpOneBorrow);
381 EXPECT_EQ(Known.Zero, APInt(8, 0xc6));
382 EXPECT_EQ(Known.One, APInt(8, 0x31));
383}
384
385TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
386 TargetLowering TL(*TM);
387
388 SDLoc Loc;
389 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
390 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: false);
391 // Create a BUILD_VECTOR
392 SDValue Op = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
393 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
394 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
395
396 APInt UndefElts;
397 APInt DemandedElts;
398 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
399
400 // Width=16, Mask=3
401 DemandedElts = APInt(16, 3);
402 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
403}
404
405TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {
406 TargetLowering TL(*TM);
407
408 SDLoc Loc;
409 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
410 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: false);
411
412 // Should create BUILD_VECTORs
413 SDValue Val1 = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
414 SDValue Val2 = DAG->getConstant(Val: 3, DL: Loc, VT: VecVT);
415 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
416 SDValue Op = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: VecVT, N1: Val1, N2: Val2);
417
418 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
419
420 APInt UndefElts;
421 APInt DemandedElts;
422 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
423
424 // Width=16, Mask=3
425 DemandedElts = APInt(16, 3);
426 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
427}
428
429TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {
430 TargetLowering TL(*TM);
431
432 SDLoc Loc;
433 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
434 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: true);
435 // Create a SPLAT_VECTOR
436 SDValue Op = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
437 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
438 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
439
440 APInt UndefElts;
441 APInt DemandedElts(1,1);
442 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
443}
444
445TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {
446 TargetLowering TL(*TM);
447
448 SDLoc Loc;
449 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
450 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: true);
451
452 // Should create SPLAT_VECTORS
453 SDValue Val1 = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
454 SDValue Val2 = DAG->getConstant(Val: 3, DL: Loc, VT: VecVT);
455 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
456 SDValue Op = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: VecVT, N1: Val1, N2: Val2);
457
458 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));
459
460 APInt UndefElts;
461 APInt DemandedElts(1, 1);
462 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));
463}
464
465TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {
466 TargetLowering TL(*TM);
467
468 SDLoc Loc;
469 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
470 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: false);
471 // Create a BUILD_VECTOR
472 SDValue Op = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
473 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);
474
475 int SplatIdx = -1;
476 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
477 EXPECT_EQ(SplatIdx, 0);
478}
479
480TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {
481 TargetLowering TL(*TM);
482
483 SDLoc Loc;
484 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
485 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: false);
486
487 // Should create BUILD_VECTORs
488 SDValue Val1 = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
489 SDValue Val2 = DAG->getConstant(Val: 3, DL: Loc, VT: VecVT);
490 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);
491 SDValue Op = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: VecVT, N1: Val1, N2: Val2);
492
493 int SplatIdx = -1;
494 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
495 EXPECT_EQ(SplatIdx, 0);
496}
497
498TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {
499 TargetLowering TL(*TM);
500
501 SDLoc Loc;
502 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
503 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: true);
504 // Create a SPLAT_VECTOR
505 SDValue Op = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
506 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);
507
508 int SplatIdx = -1;
509 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
510 EXPECT_EQ(SplatIdx, 0);
511}
512
513TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {
514 TargetLowering TL(*TM);
515
516 SDLoc Loc;
517 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
518 auto VecVT = EVT::getVectorVT(Context, VT: IntVT, NumElements: 16, IsScalable: true);
519
520 // Should create SPLAT_VECTORS
521 SDValue Val1 = DAG->getConstant(Val: 1, DL: Loc, VT: VecVT);
522 SDValue Val2 = DAG->getConstant(Val: 3, DL: Loc, VT: VecVT);
523 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);
524 SDValue Op = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: VecVT, N1: Val1, N2: Val2);
525
526 int SplatIdx = -1;
527 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);
528 EXPECT_EQ(SplatIdx, 0);
529}
530
531TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {
532 TargetLowering TL(*TM);
533
534 SDLoc Loc;
535 unsigned NumElts = 16;
536 MVT IntVT = MVT::i8;
537 MVT VecVT = MVT::getVectorVT(VT: IntVT, NumElements: NumElts);
538
539 // Base scalar constants.
540 SDValue Val0 = DAG->getConstant(Val: 0, DL: Loc, VT: IntVT);
541 SDValue Val1 = DAG->getConstant(Val: 1, DL: Loc, VT: IntVT);
542 SDValue Val2 = DAG->getConstant(Val: 2, DL: Loc, VT: IntVT);
543 SDValue Val3 = DAG->getConstant(Val: 3, DL: Loc, VT: IntVT);
544 SDValue UndefVal = DAG->getUNDEF(VT: IntVT);
545
546 // Build some repeating sequences.
547 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;
548 for(int I = 0; I != 4; ++I) {
549 Pattern1111.append(NumInputs: 4, Elt: Val1);
550 Pattern1133.append(NumInputs: 2, Elt: Val1);
551 Pattern1133.append(NumInputs: 2, Elt: Val3);
552 Pattern0123.push_back(Elt: Val0);
553 Pattern0123.push_back(Elt: Val1);
554 Pattern0123.push_back(Elt: Val2);
555 Pattern0123.push_back(Elt: Val3);
556 }
557
558 // Build a non-pow2 repeating sequence.
559 SmallVector<SDValue, 16> Pattern022;
560 Pattern022.push_back(Elt: Val0);
561 Pattern022.append(NumInputs: 2, Elt: Val2);
562 Pattern022.push_back(Elt: Val0);
563 Pattern022.append(NumInputs: 2, Elt: Val2);
564 Pattern022.push_back(Elt: Val0);
565 Pattern022.append(NumInputs: 2, Elt: Val2);
566 Pattern022.push_back(Elt: Val0);
567 Pattern022.append(NumInputs: 2, Elt: Val2);
568 Pattern022.push_back(Elt: Val0);
569 Pattern022.append(NumInputs: 2, Elt: Val2);
570 Pattern022.push_back(Elt: Val0);
571
572 // Build a non-repeating sequence.
573 SmallVector<SDValue, 16> Pattern1_3;
574 Pattern1_3.append(NumInputs: 8, Elt: Val1);
575 Pattern1_3.append(NumInputs: 8, Elt: Val3);
576
577 // Add some undefs to make it trickier.
578 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;
579 Pattern1133[0] = Pattern1133[2] = UndefVal;
580
581 auto *BV1111 =
582 cast<BuildVectorSDNode>(Val: DAG->getBuildVector(VT: VecVT, DL: Loc, Ops: Pattern1111));
583 auto *BV1133 =
584 cast<BuildVectorSDNode>(Val: DAG->getBuildVector(VT: VecVT, DL: Loc, Ops: Pattern1133));
585 auto *BV0123=
586 cast<BuildVectorSDNode>(Val: DAG->getBuildVector(VT: VecVT, DL: Loc, Ops: Pattern0123));
587 auto *BV022 =
588 cast<BuildVectorSDNode>(Val: DAG->getBuildVector(VT: VecVT, DL: Loc, Ops: Pattern022));
589 auto *BV1_3 =
590 cast<BuildVectorSDNode>(Val: DAG->getBuildVector(VT: VecVT, DL: Loc, Ops: Pattern1_3));
591
592 // Check for sequences.
593 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;
594 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;
595
596 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));
597 EXPECT_EQ(Undefs1111.count(), 3u);
598 EXPECT_EQ(Seq1111.size(), 1u);
599 EXPECT_EQ(Seq1111[0], Val1);
600
601 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));
602 EXPECT_EQ(Undefs1133.count(), 2u);
603 EXPECT_EQ(Seq1133.size(), 4u);
604 EXPECT_EQ(Seq1133[0], Val1);
605 EXPECT_EQ(Seq1133[1], Val1);
606 EXPECT_EQ(Seq1133[2], Val3);
607 EXPECT_EQ(Seq1133[3], Val3);
608
609 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));
610 EXPECT_EQ(Undefs0123.count(), 0u);
611 EXPECT_EQ(Seq0123.size(), 4u);
612 EXPECT_EQ(Seq0123[0], Val0);
613 EXPECT_EQ(Seq0123[1], Val1);
614 EXPECT_EQ(Seq0123[2], Val2);
615 EXPECT_EQ(Seq0123[3], Val3);
616
617 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));
618 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));
619
620 // Try again with DemandedElts masks.
621 APInt Mask1111_0 = APInt::getOneBitSet(numBits: NumElts, BitNo: 0);
622 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));
623 EXPECT_EQ(Undefs1111.count(), 0u);
624 EXPECT_EQ(Seq1111.size(), 1u);
625 EXPECT_EQ(Seq1111[0], Val1);
626
627 APInt Mask1111_1 = APInt::getOneBitSet(numBits: NumElts, BitNo: 2);
628 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));
629 EXPECT_EQ(Undefs1111.count(), 1u);
630 EXPECT_EQ(Seq1111.size(), 1u);
631 EXPECT_EQ(Seq1111[0], UndefVal);
632
633 APInt Mask0123 = APInt(NumElts, 0x7777);
634 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));
635 EXPECT_EQ(Undefs0123.count(), 0u);
636 EXPECT_EQ(Seq0123.size(), 4u);
637 EXPECT_EQ(Seq0123[0], Val0);
638 EXPECT_EQ(Seq0123[1], Val1);
639 EXPECT_EQ(Seq0123[2], Val2);
640 EXPECT_EQ(Seq0123[3], SDValue());
641
642 APInt Mask1_3 = APInt::getHighBitsSet(numBits: 16, hiBitsSet: 8);
643 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));
644 EXPECT_EQ(Undefs1_3.count(), 0u);
645 EXPECT_EQ(Seq1_3.size(), 1u);
646 EXPECT_EQ(Seq1_3[0], Val3);
647}
648
649TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {
650 MVT VT = MVT::nxv4i64;
651 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
652 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
653}
654
655TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {
656 MVT VT = MVT::nxv2i32;
657 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);
658 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
659}
660
661TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {
662 MVT VT = MVT::nxv1f32;
663 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);
664 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());
665}
666
667TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {
668 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);
669 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);
670 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));
671}
672
673TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {
674 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);
675 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);
676
677 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);
678 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);
679}
680
681TEST_F(AArch64SelectionDAGTest,
682 getTypeConversion_ScalarizeScalableEVT_nxv1f128) {
683 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(MinVal: 1));
684 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);
685 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);
686}
687
688TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {
689 SDLoc Loc;
690 auto IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
691 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);
692
693 // Should create SPLAT_VECTOR
694 SDValue Zero = DAG->getConstant(Val: 0, DL: Loc, VT: IntVT);
695 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);
696 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);
697}
698
699TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {
700 SDLoc Loc;
701 EVT IntVT = EVT::getIntegerVT(Context, BitWidth: 8);
702
703 SDValue N0 = DAG->getConstant(Val: 0x42, DL: Loc, VT: IntVT);
704 SDValue N1 = DAG->getRegister(Reg: 0, VT: IntVT);
705 // Construct node to fill arbitrary ExtraInfo.
706 SDValue N2 = DAG->getNode(Opcode: ISD::SUB, DL: Loc, VT: IntVT, N1: N0, N2: N1);
707 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));
708 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));
709 EXPECT_FALSE(DAG->getPCSections(N2.getNode()));
710 MDNode *MD = MDNode::get(Context, MDs: std::nullopt);
711 DAG->addHeapAllocSite(Node: N2.getNode(), MD);
712 DAG->addNoMergeSiteInfo(Node: N2.getNode(), NoMerge: true);
713 DAG->addPCSections(Node: N2.getNode(), MD);
714 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);
715 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));
716 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);
717
718 SDValue Root = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: IntVT, N1: N2, N2);
719 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);
720 // Create new node and check that ExtraInfo is propagated on RAUW.
721 SDValue New = DAG->getNode(Opcode: ISD::ADD, DL: Loc, VT: IntVT, N1, N2: N1);
722 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));
723 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));
724 EXPECT_FALSE(DAG->getPCSections(New.getNode()));
725
726 DAG->ReplaceAllUsesWith(From: N2, To: New);
727 EXPECT_EQ(Root->getOperand(0), New);
728 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);
729 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));
730 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);
731}
732
733TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_known01) {
734 SDLoc Loc;
735 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
736 auto Int32VT = EVT::getIntegerVT(Context, BitWidth: 32);
737 auto Int64VT = EVT::getIntegerVT(Context, BitWidth: 64);
738 auto Ptr = DAG->getConstant(Val: 0, DL: Loc, VT: Int64VT);
739 auto PtrInfo =
740 MachinePointerInfo::getFixedStack(MF&: DAG->getMachineFunction(), FI: 0);
741 AAMDNodes AA;
742 MDBuilder MDHelper(*DAG->getContext());
743 MDNode *Range = MDHelper.createRange(Lo: APInt(8, 0), Hi: APInt(8, 2));
744 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
745 PtrInfo, F: MachineMemOperand::MOLoad, Size: 8, BaseAlignment: Align(8), AAInfo: AA, Ranges: Range);
746
747 auto ALoad = DAG->getExtLoad(ExtType: ISD::EXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
748 Ptr, MemVT: Int8VT, MMO);
749 KnownBits Known = DAG->computeKnownBits(Op: ALoad);
750 EXPECT_EQ(Known.Zero, APInt(32, 0xfe));
751 EXPECT_EQ(Known.One, APInt(32, 0));
752
753 auto ZLoad = DAG->getExtLoad(ExtType: ISD::ZEXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
754 Ptr, MemVT: Int8VT, MMO);
755 Known = DAG->computeKnownBits(Op: ZLoad);
756 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
757 EXPECT_EQ(Known.One, APInt(32, 0));
758
759 auto SLoad = DAG->getExtLoad(ExtType: ISD::SEXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
760 Ptr, MemVT: Int8VT, MMO);
761 Known = DAG->computeKnownBits(Op: SLoad);
762 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));
763 EXPECT_EQ(Known.One, APInt(32, 0));
764}
765
766TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_knownnegative) {
767 SDLoc Loc;
768 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
769 auto Int32VT = EVT::getIntegerVT(Context, BitWidth: 32);
770 auto Int64VT = EVT::getIntegerVT(Context, BitWidth: 64);
771 auto Ptr = DAG->getConstant(Val: 0, DL: Loc, VT: Int64VT);
772 auto PtrInfo =
773 MachinePointerInfo::getFixedStack(MF&: DAG->getMachineFunction(), FI: 0);
774 AAMDNodes AA;
775 MDBuilder MDHelper(*DAG->getContext());
776 MDNode *Range = MDHelper.createRange(Lo: APInt(8, 0xf0), Hi: APInt(8, 0xff));
777 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(
778 PtrInfo, F: MachineMemOperand::MOLoad, Size: 8, BaseAlignment: Align(8), AAInfo: AA, Ranges: Range);
779
780 auto ALoad = DAG->getExtLoad(ExtType: ISD::EXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
781 Ptr, MemVT: Int8VT, MMO);
782 KnownBits Known = DAG->computeKnownBits(Op: ALoad);
783 EXPECT_EQ(Known.Zero, APInt(32, 0));
784 EXPECT_EQ(Known.One, APInt(32, 0xf0));
785
786 auto ZLoad = DAG->getExtLoad(ExtType: ISD::ZEXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
787 Ptr, MemVT: Int8VT, MMO);
788 Known = DAG->computeKnownBits(Op: ZLoad);
789 EXPECT_EQ(Known.Zero, APInt(32, 0xffffff00));
790 EXPECT_EQ(Known.One, APInt(32, 0x000000f0));
791
792 auto SLoad = DAG->getExtLoad(ExtType: ISD::SEXTLOAD, dl: Loc, VT: Int32VT, Chain: DAG->getEntryNode(),
793 Ptr, MemVT: Int8VT, MMO);
794 Known = DAG->computeKnownBits(Op: SLoad);
795 EXPECT_EQ(Known.Zero, APInt(32, 0));
796 EXPECT_EQ(Known.One, APInt(32, 0xfffffff0));
797}
798
799TEST_F(AArch64SelectionDAGTest,
800 computeKnownBits_AVGFLOORU_AVGFLOORS_AVGCEILU_AVGCEILS) {
801 SDLoc Loc;
802 auto Int8VT = EVT::getIntegerVT(Context, BitWidth: 8);
803 auto Int16VT = EVT::getIntegerVT(Context, BitWidth: 16);
804 auto Int8Vec8VT = EVT::getVectorVT(Context, VT: Int8VT, NumElements: 8);
805 auto Int16Vec8VT = EVT::getVectorVT(Context, VT: Int16VT, NumElements: 8);
806
807 SDValue UnknownOp0 = DAG->getRegister(Reg: 0, VT: Int8Vec8VT);
808 SDValue UnknownOp1 = DAG->getRegister(Reg: 1, VT: Int8Vec8VT);
809
810 SDValue ZextOp0 =
811 DAG->getNode(Opcode: ISD::ZERO_EXTEND, DL: Loc, VT: Int16Vec8VT, Operand: UnknownOp0);
812 SDValue ZextOp1 =
813 DAG->getNode(Opcode: ISD::ZERO_EXTEND, DL: Loc, VT: Int16Vec8VT, Operand: UnknownOp1);
814 // ZextOp0 = 00000000????????
815 // ZextOp1 = 00000000????????
816 // => (for all AVG* instructions)
817 // Known.Zero = 1111111100000000 (0xFF00)
818 // Known.One = 0000000000000000 (0x0000)
819 auto Zeroes = APInt(16, 0xFF00);
820 auto Ones = APInt(16, 0x0000);
821
822 SDValue AVGFLOORU =
823 DAG->getNode(Opcode: ISD::AVGFLOORU, DL: Loc, VT: Int16Vec8VT, N1: ZextOp0, N2: ZextOp1);
824 KnownBits KnownAVGFLOORU = DAG->computeKnownBits(Op: AVGFLOORU);
825 EXPECT_EQ(KnownAVGFLOORU.Zero, Zeroes);
826 EXPECT_EQ(KnownAVGFLOORU.One, Ones);
827
828 SDValue AVGFLOORS =
829 DAG->getNode(Opcode: ISD::AVGFLOORS, DL: Loc, VT: Int16Vec8VT, N1: ZextOp0, N2: ZextOp1);
830 KnownBits KnownAVGFLOORS = DAG->computeKnownBits(Op: AVGFLOORS);
831 EXPECT_EQ(KnownAVGFLOORS.Zero, Zeroes);
832 EXPECT_EQ(KnownAVGFLOORS.One, Ones);
833
834 SDValue AVGCEILU =
835 DAG->getNode(Opcode: ISD::AVGCEILU, DL: Loc, VT: Int16Vec8VT, N1: ZextOp0, N2: ZextOp1);
836 KnownBits KnownAVGCEILU = DAG->computeKnownBits(Op: AVGCEILU);
837 EXPECT_EQ(KnownAVGCEILU.Zero, Zeroes);
838 EXPECT_EQ(KnownAVGCEILU.One, Ones);
839
840 SDValue AVGCEILS =
841 DAG->getNode(Opcode: ISD::AVGCEILS, DL: Loc, VT: Int16Vec8VT, N1: ZextOp0, N2: ZextOp1);
842 KnownBits KnownAVGCEILS = DAG->computeKnownBits(Op: AVGCEILS);
843 EXPECT_EQ(KnownAVGCEILS.Zero, Zeroes);
844 EXPECT_EQ(KnownAVGCEILS.One, Ones);
845}
846
847} // end namespace llvm
848

source code of llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp