1 //===- llvm/unittest/CodeGen/AArch64SelectionDAGTest.cpp -------------------------===//
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 "llvm/CodeGen/SelectionDAG.h"
10 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/CodeGen/MachineModuleInfo.h"
13 #include "llvm/CodeGen/TargetLowering.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "llvm/Support/TargetRegistry.h"
16 #include "llvm/Support/TargetSelect.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "gtest/gtest.h"
24 class AArch64SelectionDAGTest
: public testing::Test
{
26 static void SetUpTestCase() {
27 InitializeAllTargets();
28 InitializeAllTargetMCs();
31 void SetUp() override
{
32 StringRef Assembly
= "define void @f() { ret void }";
34 Triple
TargetTriple("aarch64--");
36 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
37 // FIXME: These tests do not depend on AArch64 specifically, but we have to
38 // initialize a target. A skeleton Target for unittests would allow us to
39 // always run these tests.
43 TargetOptions Options
;
44 TM
= std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
45 T
->createTargetMachine("AArch64", "", "", Options
, None
, None
,
46 CodeGenOpt::Aggressive
)));
51 M
= parseAssemblyString(Assembly
, SMError
, Context
);
53 report_fatal_error(SMError
.getMessage());
54 M
->setDataLayout(TM
->createDataLayout());
56 F
= M
->getFunction("f");
58 report_fatal_error("F?");
60 MachineModuleInfo
MMI(TM
.get());
62 MF
= std::make_unique
<MachineFunction
>(*F
, *TM
, *TM
->getSubtargetImpl(*F
), 0,
65 DAG
= std::make_unique
<SelectionDAG
>(*TM
, CodeGenOpt::None
);
67 report_fatal_error("DAG?");
68 OptimizationRemarkEmitter
ORE(F
);
69 DAG
->init(*MF
, ORE
, nullptr, nullptr, nullptr);
73 std::unique_ptr
<LLVMTargetMachine
> TM
;
74 std::unique_ptr
<Module
> M
;
76 std::unique_ptr
<MachineFunction
> MF
;
77 std::unique_ptr
<SelectionDAG
> DAG
;
80 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_ZERO_EXTEND_VECTOR_INREG
) {
84 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
85 auto Int16VT
= EVT::getIntegerVT(Context
, 16);
86 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 4);
87 auto OutVecVT
= EVT::getVectorVT(Context
, Int16VT
, 2);
88 auto InVec
= DAG
->getConstant(0, Loc
, InVecVT
);
89 auto Op
= DAG
->getNode(ISD::ZERO_EXTEND_VECTOR_INREG
, Loc
, OutVecVT
, InVec
);
90 auto DemandedElts
= APInt(2, 3);
91 KnownBits Known
= DAG
->computeKnownBits(Op
, DemandedElts
);
92 EXPECT_TRUE(Known
.isZero());
95 TEST_F(AArch64SelectionDAGTest
, computeKnownBits_EXTRACT_SUBVECTOR
) {
99 auto IntVT
= EVT::getIntegerVT(Context
, 8);
100 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
101 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
102 auto Vec
= DAG
->getConstant(0, Loc
, VecVT
);
103 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
104 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
105 auto DemandedElts
= APInt(3, 7);
106 KnownBits Known
= DAG
->computeKnownBits(Op
, DemandedElts
);
107 EXPECT_TRUE(Known
.isZero());
110 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG
) {
114 auto Int8VT
= EVT::getIntegerVT(Context
, 8);
115 auto Int16VT
= EVT::getIntegerVT(Context
, 16);
116 auto InVecVT
= EVT::getVectorVT(Context
, Int8VT
, 4);
117 auto OutVecVT
= EVT::getVectorVT(Context
, Int16VT
, 2);
118 auto InVec
= DAG
->getConstant(1, Loc
, InVecVT
);
119 auto Op
= DAG
->getNode(ISD::SIGN_EXTEND_VECTOR_INREG
, Loc
, OutVecVT
, InVec
);
120 auto DemandedElts
= APInt(2, 3);
121 EXPECT_EQ(DAG
->ComputeNumSignBits(Op
, DemandedElts
), 15u);
124 TEST_F(AArch64SelectionDAGTest
, ComputeNumSignBits_EXTRACT_SUBVECTOR
) {
128 auto IntVT
= EVT::getIntegerVT(Context
, 8);
129 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
130 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
131 auto Vec
= DAG
->getConstant(1, Loc
, VecVT
);
132 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
133 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
134 auto DemandedElts
= APInt(3, 7);
135 EXPECT_EQ(DAG
->ComputeNumSignBits(Op
, DemandedElts
), 7u);
138 TEST_F(AArch64SelectionDAGTest
, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR
) {
142 TargetLowering
TL(*TM
);
145 auto IntVT
= EVT::getIntegerVT(Context
, 8);
146 auto VecVT
= EVT::getVectorVT(Context
, IntVT
, 3);
147 auto IdxVT
= EVT::getIntegerVT(Context
, 64);
148 auto Vec
= DAG
->getConstant(1, Loc
, VecVT
);
149 auto ZeroIdx
= DAG
->getConstant(0, Loc
, IdxVT
);
150 auto Op
= DAG
->getNode(ISD::EXTRACT_SUBVECTOR
, Loc
, VecVT
, Vec
, ZeroIdx
);
151 auto DemandedElts
= APInt(3, 7);
152 auto KnownUndef
= APInt(3, 0);
153 auto KnownZero
= APInt(3, 0);
154 TargetLowering::TargetLoweringOpt
TLO(*DAG
, false, false);
155 EXPECT_EQ(TL
.SimplifyDemandedVectorElts(Op
, DemandedElts
, KnownUndef
,
160 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
161 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_ADD
) {
165 auto IntVT
= EVT::getIntegerVT(Context
, 8);
166 auto UnknownOp
= DAG
->getRegister(0, IntVT
);
167 auto Mask
= DAG
->getConstant(0x8A, Loc
, IntVT
);
168 auto N0
= DAG
->getNode(ISD::AND
, Loc
, IntVT
, Mask
, UnknownOp
);
169 auto N1
= DAG
->getConstant(0x55, Loc
, IntVT
);
170 auto Op
= DAG
->getNode(ISD::ADD
, Loc
, IntVT
, N0
, N1
);
174 // Known.One = 01010101 (0x55)
175 // Known.Zero = 00100000 (0x20)
176 KnownBits Known
= DAG
->computeKnownBits(Op
);
177 EXPECT_EQ(Known
.Zero
, APInt(8, 0x20));
178 EXPECT_EQ(Known
.One
, APInt(8, 0x55));
181 // Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
182 TEST_F(AArch64SelectionDAGTest
, ComputeKnownBits_SUB
) {
186 auto IntVT
= EVT::getIntegerVT(Context
, 8);
187 auto N0
= DAG
->getConstant(0x55, Loc
, IntVT
);
188 auto UnknownOp
= DAG
->getRegister(0, IntVT
);
189 auto Mask
= DAG
->getConstant(0x2e, Loc
, IntVT
);
190 auto N1
= DAG
->getNode(ISD::AND
, Loc
, IntVT
, Mask
, UnknownOp
);
191 auto Op
= DAG
->getNode(ISD::SUB
, Loc
, IntVT
, N0
, N1
);
195 // Known.One = 00000001 (0x1)
196 // Known.Zero = 10000000 (0x80)
197 KnownBits Known
= DAG
->computeKnownBits(Op
);
198 EXPECT_EQ(Known
.Zero
, APInt(8, 0x80));
199 EXPECT_EQ(Known
.One
, APInt(8, 0x1));
202 } // end anonymous namespace