1253 lines · cpp
1//===----------------------------------------------------------------------===//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7 8#include "AArch64SelectionDAGInfo.h"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/IR/Module.h"17#include "llvm/MC/TargetRegistry.h"18#include "llvm/Support/KnownBits.h"19#include "llvm/Support/SourceMgr.h"20#include "llvm/Support/TargetSelect.h"21#include "llvm/Target/TargetMachine.h"22#include "gtest/gtest.h"23 24namespace llvm {25 26class AArch64SelectionDAGTest : public testing::Test {27protected:28 const TargetSubtargetInfo *STI;29 30 static void SetUpTestCase() {31 LLVMInitializeAArch64TargetInfo();32 LLVMInitializeAArch64Target();33 LLVMInitializeAArch64TargetMC();34 }35 36 void SetUp() override {37 StringRef Assembly = "define void @f() { ret void }";38 39 Triple TargetTriple("aarch64--");40 std::string Error;41 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);42 43 TargetOptions Options;44 TM = std::unique_ptr<TargetMachine>(45 T->createTargetMachine(TargetTriple, "", "+sve", Options, std::nullopt,46 std::nullopt, CodeGenOptLevel::Aggressive));47 48 SMDiagnostic SMError;49 M = parseAssemblyString(Assembly, SMError, Context);50 if (!M)51 report_fatal_error(SMError.getMessage());52 M->setDataLayout(TM->createDataLayout());53 54 F = M->getFunction("f");55 if (!F)56 report_fatal_error("F?");57 58 MachineModuleInfo MMI(TM.get());59 60 STI = TM->getSubtargetImpl(*F);61 MF = std::make_unique<MachineFunction>(*F, *TM, *STI, MMI.getContext(), 0);62 63 DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);64 if (!DAG)65 report_fatal_error("DAG?");66 OptimizationRemarkEmitter ORE(F);67 DAG->init(*MF, ORE, nullptr, nullptr, nullptr, nullptr, nullptr, MMI,68 nullptr);69 }70 71 TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {72 return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);73 }74 75 EVT getTypeToTransformTo(EVT VT) {76 return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);77 }78 79 LLVMContext Context;80 std::unique_ptr<TargetMachine> TM;81 std::unique_ptr<Module> M;82 Function *F;83 std::unique_ptr<MachineFunction> MF;84 std::unique_ptr<SelectionDAG> DAG;85};86 87TEST_F(AArch64SelectionDAGTest, computeKnownBits_ZERO_EXTEND_VECTOR_INREG) {88 SDLoc Loc;89 auto Int8VT = EVT::getIntegerVT(Context, 8);90 auto Int16VT = EVT::getIntegerVT(Context, 16);91 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);92 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);93 auto InVec = DAG->getConstant(0, Loc, InVecVT);94 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);95 auto DemandedElts = APInt(2, 3);96 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);97 EXPECT_TRUE(Known.isZero());98}99 100TEST_F(AArch64SelectionDAGTest, computeKnownBitsSVE_ZERO_EXTEND_VECTOR_INREG) {101 SDLoc Loc;102 auto Int8VT = EVT::getIntegerVT(Context, 8);103 auto Int16VT = EVT::getIntegerVT(Context, 16);104 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, true);105 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, true);106 auto InVec = DAG->getConstant(0, Loc, InVecVT);107 auto Op = DAG->getNode(ISD::ZERO_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);108 auto DemandedElts = APInt(2, 3);109 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);110 111 // We don't know anything for SVE at the moment.112 EXPECT_EQ(Known.Zero, APInt(16, 0u));113 EXPECT_EQ(Known.One, APInt(16, 0u));114 EXPECT_FALSE(Known.isZero());115}116 117TEST_F(AArch64SelectionDAGTest, computeKnownBits_EXTRACT_SUBVECTOR) {118 SDLoc Loc;119 auto IntVT = EVT::getIntegerVT(Context, 8);120 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);121 auto IdxVT = EVT::getIntegerVT(Context, 64);122 auto Vec = DAG->getConstant(0, Loc, VecVT);123 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);124 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);125 auto DemandedElts = APInt(3, 7);126 KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);127 EXPECT_TRUE(Known.isZero());128}129 130TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SIGN_EXTEND_VECTOR_INREG) {131 SDLoc Loc;132 auto Int8VT = EVT::getIntegerVT(Context, 8);133 auto Int16VT = EVT::getIntegerVT(Context, 16);134 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4);135 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2);136 auto InVec = DAG->getConstant(1, Loc, InVecVT);137 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);138 auto DemandedElts = APInt(2, 3);139 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 15u);140}141 142TEST_F(AArch64SelectionDAGTest,143 ComputeNumSignBitsSVE_SIGN_EXTEND_VECTOR_INREG) {144 SDLoc Loc;145 auto Int8VT = EVT::getIntegerVT(Context, 8);146 auto Int16VT = EVT::getIntegerVT(Context, 16);147 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 4, /*IsScalable=*/true);148 auto OutVecVT = EVT::getVectorVT(Context, Int16VT, 2, /*IsScalable=*/true);149 auto InVec = DAG->getConstant(1, Loc, InVecVT);150 auto Op = DAG->getNode(ISD::SIGN_EXTEND_VECTOR_INREG, Loc, OutVecVT, InVec);151 auto DemandedElts = APInt(2, 3);152 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 1u);153}154 155TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_EXTRACT_SUBVECTOR) {156 SDLoc Loc;157 auto IntVT = EVT::getIntegerVT(Context, 8);158 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);159 auto IdxVT = EVT::getIntegerVT(Context, 64);160 auto Vec = DAG->getConstant(1, Loc, VecVT);161 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);162 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);163 auto DemandedElts = APInt(3, 7);164 EXPECT_EQ(DAG->ComputeNumSignBits(Op, DemandedElts), 7u);165}166 167TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_VASHR) {168 SDLoc Loc;169 auto VecVT = MVT::v8i8;170 auto Shift = DAG->getConstant(4, Loc, MVT::i32);171 auto Vec0 = DAG->getConstant(1, Loc, VecVT);172 auto Op1 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, Vec0, Shift);173 EXPECT_EQ(DAG->ComputeNumSignBits(Op1), 8u);174 auto VecA = DAG->getConstant(0xaa, Loc, VecVT);175 auto Op2 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, VecA, Shift);176 EXPECT_EQ(DAG->ComputeNumSignBits(Op2), 5u);177 // VASHR can't create undef/poison - FREEZE(VASHR(C1,C2)) -> VASHR(C1,C2).178 auto Fr2 = DAG->getFreeze(Op2);179 EXPECT_EQ(DAG->ComputeNumSignBits(Fr2), 5u);180}181 182TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_SUB) {183 SDLoc Loc;184 auto IntVT = EVT::getIntegerVT(Context, 8);185 auto N0 = DAG->getConstant(0x00, Loc, IntVT);186 auto N1 = DAG->getConstant(0x01, Loc, IntVT);187 auto N5 = DAG->getConstant(0x05, Loc, IntVT);188 auto Nsign1 = DAG->getConstant(0x55, Loc, IntVT);189 auto UnknownOp = DAG->getRegister(0, IntVT);190 auto Mask = DAG->getConstant(0x1e, Loc, IntVT);191 auto Nsign3 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);192 // RHS early out193 // Nsign1 = 01010101194 // Nsign3 = 000????0195 auto OpRhsEo = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign3, Nsign1);196 EXPECT_EQ(DAG->ComputeNumSignBits(OpRhsEo), 1u);197 198 // Neg 0199 // N0 = 00000000200 auto OpNegZero = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N0);201 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegZero), 8u);202 203 // Neg 1204 // N0 = 00000000205 // N1 = 00000001206 auto OpNegOne = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);207 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegOne), 8u);208 209 // Neg 5210 // N0 = 00000000211 // N5 = 00000101212 auto OpNegFive = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N5);213 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegFive), 5u);214 215 // Non negative216 // N0 = 00000000217 // Nsign3 = 000????0218 auto OpNonNeg = DAG->getNode(ISD::SUB, Loc, IntVT, N0, Nsign3);219 EXPECT_EQ(DAG->ComputeNumSignBits(OpNonNeg), 3u);220 221 // LHS early out222 // Nsign1 = 01010101223 // Nsign3 = 000????0224 auto OpLhsEo = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign1, Nsign3);225 EXPECT_EQ(DAG->ComputeNumSignBits(OpLhsEo), 1u);226 227 // Nsign3 = 000????0228 // N5 = 00000101229 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, Nsign3, N5);230 EXPECT_EQ(DAG->ComputeNumSignBits(Op), 2u);231}232 233TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_ADD) {234 SDLoc Loc;235 auto IntVT = EVT::getIntegerVT(Context, 8);236 auto Nneg1 = DAG->getConstant(0xFF, Loc, IntVT);237 auto N0 = DAG->getConstant(0x00, Loc, IntVT);238 auto N1 = DAG->getConstant(0x01, Loc, IntVT);239 auto N5 = DAG->getConstant(0x05, Loc, IntVT);240 auto N8 = DAG->getConstant(0x08, Loc, IntVT);241 auto Nsign1 = DAG->getConstant(0x55, Loc, IntVT);242 auto UnknownOp = DAG->getRegister(0, IntVT);243 auto Mask = DAG->getConstant(0x1e, Loc, IntVT);244 auto Nsign3 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);245 // RHS early out246 // Nsign1 = 01010101247 // Nsign3 = 000????0248 auto OpRhsEo = DAG->getNode(ISD::ADD, Loc, IntVT, Nsign3, Nsign1);249 EXPECT_EQ(DAG->ComputeNumSignBits(OpRhsEo), 1u);250 251 // ADD 0 -1252 // N0 = 00000000253 // Nneg1 = 11111111254 auto OpNegZero = DAG->getNode(ISD::ADD, Loc, IntVT, N0, Nneg1);255 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegZero), 8u);256 257 // ADD 1 -1258 // N1 = 00000001259 // Nneg1 = 11111111260 auto OpNegOne = DAG->getNode(ISD::ADD, Loc, IntVT, N1, Nneg1);261 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegOne), 8u);262 263 // ADD 8 -1264 // N8 = 00001000265 // Nneg1 = 11111111266 auto OpSeven = DAG->getNode(ISD::ADD, Loc, IntVT, N8, Nneg1);267 EXPECT_EQ(DAG->ComputeNumSignBits(OpSeven), 5u);268 269 // Non negative270 // Nsign3 = 000????0271 // Nneg1 = 11111111272 auto OpNonNeg = DAG->getNode(ISD::ADD, Loc, IntVT, Nsign3, Nneg1);273 EXPECT_EQ(DAG->ComputeNumSignBits(OpNonNeg), 3u);274 275 // LHS early out276 // Nsign1 = 01010101277 // Nsign3 = 000????0278 auto OpLhsEo = DAG->getNode(ISD::ADD, Loc, IntVT, Nsign1, Nsign3);279 EXPECT_EQ(DAG->ComputeNumSignBits(OpLhsEo), 1u);280 281 // Nsign3 = 000????0282 // N5 = 00000101283 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, Nsign3, N5);284 EXPECT_EQ(DAG->ComputeNumSignBits(Op), 2u);285}286 287TEST_F(AArch64SelectionDAGTest, ComputeNumSignBits_ADDC) {288 SDLoc Loc;289 auto IntVT = EVT::getIntegerVT(Context, 8);290 auto Nneg1 = DAG->getConstant(0xFF, Loc, IntVT);291 auto N0 = DAG->getConstant(0x00, Loc, IntVT);292 auto N1 = DAG->getConstant(0x01, Loc, IntVT);293 auto N5 = DAG->getConstant(0x05, Loc, IntVT);294 auto N8 = DAG->getConstant(0x08, Loc, IntVT);295 auto Nsign1 = DAG->getConstant(0x55, Loc, IntVT);296 auto UnknownOp = DAG->getRegister(0, IntVT);297 auto Mask = DAG->getConstant(0x1e, Loc, IntVT);298 auto Nsign3 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);299 // RHS early out300 // Nsign1 = 01010101301 // Nsign3 = 000????0302 auto OpRhsEo = DAG->getNode(ISD::ADDC, Loc, IntVT, Nsign3, Nsign1);303 EXPECT_EQ(DAG->ComputeNumSignBits(OpRhsEo), 1u);304 305 // ADD 0 -1306 // N0 = 00000000307 // Nneg1 = 11111111308 auto OpNegZero = DAG->getNode(ISD::ADDC, Loc, IntVT, N0, Nneg1);309 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegZero), 8u);310 311 // ADD 1 -1312 // N1 = 00000001313 // Nneg1 = 11111111314 auto OpNegOne = DAG->getNode(ISD::ADDC, Loc, IntVT, N1, Nneg1);315 EXPECT_EQ(DAG->ComputeNumSignBits(OpNegOne), 8u);316 317 // ADD 8 -1318 // N8 = 00001000319 // Nneg1 = 11111111320 auto OpSeven = DAG->getNode(ISD::ADDC, Loc, IntVT, N8, Nneg1);321 EXPECT_EQ(DAG->ComputeNumSignBits(OpSeven), 4u);322 323 // Non negative324 // Nsign3 = 000????0325 // Nneg1 = 11111111326 auto OpNonNeg = DAG->getNode(ISD::ADDC, Loc, IntVT, Nsign3, Nneg1);327 EXPECT_EQ(DAG->ComputeNumSignBits(OpNonNeg), 3u);328 329 // LHS early out330 // Nsign1 = 01010101331 // Nsign3 = 000????0332 auto OpLhsEo = DAG->getNode(ISD::ADDC, Loc, IntVT, Nsign1, Nsign3);333 EXPECT_EQ(DAG->ComputeNumSignBits(OpLhsEo), 1u);334 335 // Nsign3 = 000????0336 // N5 = 00000101337 auto Op = DAG->getNode(ISD::ADDC, Loc, IntVT, Nsign3, N5);338 EXPECT_EQ(DAG->ComputeNumSignBits(Op), 2u);339}340 341TEST_F(AArch64SelectionDAGTest, SimplifyDemandedVectorElts_EXTRACT_SUBVECTOR) {342 TargetLowering TL(*TM, *STI);343 344 SDLoc Loc;345 auto IntVT = EVT::getIntegerVT(Context, 8);346 auto VecVT = EVT::getVectorVT(Context, IntVT, 3);347 auto IdxVT = EVT::getIntegerVT(Context, 64);348 auto Vec = DAG->getConstant(1, Loc, VecVT);349 auto ZeroIdx = DAG->getConstant(0, Loc, IdxVT);350 auto Op = DAG->getNode(ISD::EXTRACT_SUBVECTOR, Loc, VecVT, Vec, ZeroIdx);351 auto DemandedElts = APInt(3, 7);352 auto KnownUndef = APInt(3, 0);353 auto KnownZero = APInt(3, 0);354 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);355 EXPECT_EQ(TL.SimplifyDemandedVectorElts(Op, DemandedElts, KnownUndef,356 KnownZero, TLO),357 false);358}359 360TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsNEON) {361 TargetLowering TL(*TM, *STI);362 363 SDLoc Loc;364 auto Int8VT = EVT::getIntegerVT(Context, 8);365 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16);366 SDValue UnknownOp = DAG->getRegister(0, InVecVT);367 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);368 SDValue Mask1V = DAG->getSplatBuildVector(InVecVT, Loc, Mask1S);369 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);370 371 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);372 SDValue Mask2V = DAG->getSplatBuildVector(InVecVT, Loc, Mask2S);373 374 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);375 // N0 = ?000?0?0376 // Mask2V = 01010101377 // =>378 // Known.Zero = 00100000 (0xAA)379 KnownBits Known;380 APInt DemandedBits = APInt(8, 0xFF);381 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);382 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));383 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));384}385 386TEST_F(AArch64SelectionDAGTest, SimplifyDemandedBitsSVE) {387 TargetLowering TL(*TM, *STI);388 389 SDLoc Loc;390 auto Int8VT = EVT::getIntegerVT(Context, 8);391 auto InVecVT = EVT::getVectorVT(Context, Int8VT, 16, /*IsScalable=*/true);392 SDValue UnknownOp = DAG->getRegister(0, InVecVT);393 SDValue Mask1S = DAG->getConstant(0x8A, Loc, Int8VT);394 SDValue Mask1V = DAG->getSplatVector(InVecVT, Loc, Mask1S);395 SDValue N0 = DAG->getNode(ISD::AND, Loc, InVecVT, Mask1V, UnknownOp);396 397 SDValue Mask2S = DAG->getConstant(0x55, Loc, Int8VT);398 SDValue Mask2V = DAG->getSplatVector(InVecVT, Loc, Mask2S);399 400 SDValue Op = DAG->getNode(ISD::AND, Loc, InVecVT, N0, Mask2V);401 402 // N0 = ?000?0?0403 // Mask2V = 01010101404 // =>405 // Known.Zero = 00100000 (0xAA)406 KnownBits Known;407 APInt DemandedBits = APInt(8, 0xFF);408 TargetLowering::TargetLoweringOpt TLO(*DAG, false, false);409 EXPECT_TRUE(TL.SimplifyDemandedBits(Op, DemandedBits, Known, TLO));410 EXPECT_EQ(Known.Zero, APInt(8, 0xAA));411}412 413// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.414TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_ADD) {415 SDLoc Loc;416 auto IntVT = EVT::getIntegerVT(Context, 8);417 auto UnknownOp = DAG->getRegister(0, IntVT);418 auto Mask = DAG->getConstant(0x8A, Loc, IntVT);419 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);420 auto N1 = DAG->getConstant(0x55, Loc, IntVT);421 auto Op = DAG->getNode(ISD::ADD, Loc, IntVT, N0, N1);422 // N0 = ?000?0?0423 // N1 = 01010101424 // =>425 // Known.One = 01010101 (0x55)426 // Known.Zero = 00100000 (0x20)427 KnownBits Known = DAG->computeKnownBits(Op);428 EXPECT_EQ(Known.Zero, APInt(8, 0x20));429 EXPECT_EQ(Known.One, APInt(8, 0x55));430}431 432// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.433TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_UADDO_CARRY) {434 SDLoc Loc;435 auto IntVT = EVT::getIntegerVT(Context, 8);436 auto UnknownOp = DAG->getRegister(0, IntVT);437 auto Mask_Zero = DAG->getConstant(0x28, Loc, IntVT);438 auto Mask_One = DAG->getConstant(0x20, Loc, IntVT);439 auto N0 = DAG->getNode(ISD::AND, Loc, IntVT, Mask_Zero, UnknownOp);440 N0 = DAG->getNode(ISD::OR, Loc, IntVT, Mask_One, N0);441 auto N1 = DAG->getConstant(0x65, Loc, IntVT);442 443 KnownBits Known;444 445 auto UnknownBorrow = DAG->getRegister(1, IntVT);446 auto OpUnknownBorrow =447 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);448 // N0 = 0010?000449 // N1 = 01100101450 // B = ?451 // =>452 // Known.Zero = 01110000 (0x70)453 // Known.One = 10000100 (0x84)454 Known = DAG->computeKnownBits(OpUnknownBorrow);455 EXPECT_EQ(Known.Zero, APInt(8, 0x70));456 EXPECT_EQ(Known.One, APInt(8, 0x84));457 458 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);459 auto OpZeroBorrow =460 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);461 // N0 = 0010?000462 // N1 = 01100101463 // B = 0464 // =>465 // Known.Zero = 01110010 (0x72)466 // Known.One = 10000101 (0x85)467 Known = DAG->computeKnownBits(OpZeroBorrow);468 EXPECT_EQ(Known.Zero, APInt(8, 0x72));469 EXPECT_EQ(Known.One, APInt(8, 0x85));470 471 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);472 auto OpOneBorrow =473 DAG->getNode(ISD::UADDO_CARRY, Loc, IntVT, N0, N1, OneBorrow);474 // N0 = 0010?000475 // N1 = 01100101476 // B = 1477 // =>478 // Known.Zero = 01110001 (0x71)479 // Known.One = 10000110 (0x86)480 Known = DAG->computeKnownBits(OpOneBorrow);481 EXPECT_EQ(Known.Zero, APInt(8, 0x71));482 EXPECT_EQ(Known.One, APInt(8, 0x86));483}484 485// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.486// Attempt to FREEZE the MOV/MVN nodes to show that they can still be analysed.487TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_MOVI) {488 SDLoc Loc;489 auto IntSca32VT = MVT::i32;490 auto Int8Vec8VT = MVT::v8i8;491 auto Int16Vec8VT = MVT::v16i8;492 auto Int4Vec16VT = MVT::v4i16;493 auto Int8Vec16VT = MVT::v8i16;494 auto Int2Vec32VT = MVT::v2i32;495 auto Int4Vec32VT = MVT::v4i32;496 auto IntVec64VT = MVT::v1i64;497 auto Int2Vec64VT = MVT::v2i64;498 auto N165 = DAG->getConstant(0x000000A5, Loc, IntSca32VT);499 KnownBits Known;500 501 auto OpMOVIedit64 = DAG->getNode(AArch64ISD::MOVIedit, Loc, IntVec64VT, N165);502 Known = DAG->computeKnownBits(OpMOVIedit64);503 EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));504 EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));505 506 auto OpMOVIedit128 =507 DAG->getNode(AArch64ISD::MOVIedit, Loc, Int2Vec64VT, N165);508 Known = DAG->computeKnownBits(OpMOVIedit128);509 EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));510 EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));511 512 auto FrMOVIedit128 = DAG->getFreeze(OpMOVIedit128);513 Known = DAG->computeKnownBits(FrMOVIedit128);514 EXPECT_EQ(Known.Zero, APInt(64, 0x00FF00FFFF00FF00));515 EXPECT_EQ(Known.One, APInt(64, 0xFF00FF0000FF00FF));516 517 auto N264 = DAG->getConstant(264, Loc, IntSca32VT);518 auto OpMOVImsl64 =519 DAG->getNode(AArch64ISD::MOVImsl, Loc, Int2Vec32VT, N165, N264);520 Known = DAG->computeKnownBits(OpMOVImsl64);521 EXPECT_EQ(Known.Zero, APInt(32, 0xFFFF5A00));522 EXPECT_EQ(Known.One, APInt(32, 0x0000A5FF));523 524 auto N272 = DAG->getConstant(272, Loc, IntSca32VT);525 auto OpMOVImsl128 =526 DAG->getNode(AArch64ISD::MOVImsl, Loc, Int4Vec32VT, N165, N272);527 Known = DAG->computeKnownBits(OpMOVImsl128);528 EXPECT_EQ(Known.Zero, APInt(32, 0xFF5A0000));529 EXPECT_EQ(Known.One, APInt(32, 0x00A5FFFF));530 531 auto FrMOVImsl128 = DAG->getFreeze(OpMOVImsl128);532 Known = DAG->computeKnownBits(FrMOVImsl128);533 EXPECT_EQ(Known.Zero, APInt(32, 0xFF5A0000));534 EXPECT_EQ(Known.One, APInt(32, 0x00A5FFFF));535 536 auto OpMVNImsl64 =537 DAG->getNode(AArch64ISD::MVNImsl, Loc, Int2Vec32VT, N165, N272);538 Known = DAG->computeKnownBits(OpMVNImsl64);539 EXPECT_EQ(Known.Zero, APInt(32, 0x00A5FFFF));540 EXPECT_EQ(Known.One, APInt(32, 0xFF5A0000));541 542 auto OpMVNImsl128 =543 DAG->getNode(AArch64ISD::MVNImsl, Loc, Int4Vec32VT, N165, N264);544 Known = DAG->computeKnownBits(OpMVNImsl128);545 EXPECT_EQ(Known.Zero, APInt(32, 0x0000A5FF));546 EXPECT_EQ(Known.One, APInt(32, 0xFFFF5A00));547 548 auto FrMVNImsl128 = DAG->getFreeze(OpMVNImsl128);549 Known = DAG->computeKnownBits(FrMVNImsl128);550 EXPECT_EQ(Known.Zero, APInt(32, 0x0000A5FF));551 EXPECT_EQ(Known.One, APInt(32, 0xFFFF5A00));552 553 auto N0 = DAG->getConstant(0, Loc, IntSca32VT);554 auto OpMOVIshift2Vec32 =555 DAG->getNode(AArch64ISD::MOVIshift, Loc, Int2Vec32VT, N165, N0);556 Known = DAG->computeKnownBits(OpMOVIshift2Vec32);557 EXPECT_EQ(Known.Zero, APInt(32, 0xFFFFFF5A));558 EXPECT_EQ(Known.One, APInt(32, 0x000000A5));559 560 auto N24 = DAG->getConstant(24, Loc, IntSca32VT);561 auto OpMOVIshift4Vec32 =562 DAG->getNode(AArch64ISD::MOVIshift, Loc, Int4Vec32VT, N165, N24);563 Known = DAG->computeKnownBits(OpMOVIshift4Vec32);564 EXPECT_EQ(Known.Zero, APInt(32, 0x5AFFFFFF));565 EXPECT_EQ(Known.One, APInt(32, 0xA5000000));566 567 auto FrMOVIshift4Vec32 = DAG->getFreeze(OpMOVIshift4Vec32);568 Known = DAG->computeKnownBits(FrMOVIshift4Vec32);569 EXPECT_EQ(Known.Zero, APInt(32, 0x5AFFFFFF));570 EXPECT_EQ(Known.One, APInt(32, 0xA5000000));571 572 auto OpMVNIshift2Vec32 =573 DAG->getNode(AArch64ISD::MVNIshift, Loc, Int2Vec32VT, N165, N24);574 Known = DAG->computeKnownBits(OpMVNIshift2Vec32);575 EXPECT_EQ(Known.Zero, APInt(32, 0xA5000000));576 EXPECT_EQ(Known.One, APInt(32, 0x5AFFFFFF));577 578 auto OpMVNIshift4Vec32 =579 DAG->getNode(AArch64ISD::MVNIshift, Loc, Int4Vec32VT, N165, N0);580 Known = DAG->computeKnownBits(OpMVNIshift4Vec32);581 EXPECT_EQ(Known.Zero, APInt(32, 0x000000A5));582 EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF5A));583 584 auto FrMVNIshift4Vec32 = DAG->getFreeze(OpMVNIshift4Vec32);585 Known = DAG->computeKnownBits(FrMVNIshift4Vec32);586 EXPECT_EQ(Known.Zero, APInt(32, 0x000000A5));587 EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF5A));588 589 auto N8 = DAG->getConstant(8, Loc, IntSca32VT);590 auto OpMOVIshift4Vec16 =591 DAG->getNode(AArch64ISD::MOVIshift, Loc, Int4Vec16VT, N165, N0);592 Known = DAG->computeKnownBits(OpMOVIshift4Vec16);593 EXPECT_EQ(Known.Zero, APInt(16, 0xFF5A));594 EXPECT_EQ(Known.One, APInt(16, 0x00A5));595 596 auto OpMOVIshift8Vec16 =597 DAG->getNode(AArch64ISD::MOVIshift, Loc, Int8Vec16VT, N165, N8);598 Known = DAG->computeKnownBits(OpMOVIshift8Vec16);599 EXPECT_EQ(Known.Zero, APInt(16, 0x5AFF));600 EXPECT_EQ(Known.One, APInt(16, 0xA500));601 602 auto FrMOVIshift8Vec16 = DAG->getFreeze(OpMOVIshift8Vec16);603 Known = DAG->computeKnownBits(FrMOVIshift8Vec16);604 EXPECT_EQ(Known.Zero, APInt(16, 0x5AFF));605 EXPECT_EQ(Known.One, APInt(16, 0xA500));606 607 auto OpMVNIshift4Vec16 =608 DAG->getNode(AArch64ISD::MVNIshift, Loc, Int4Vec16VT, N165, N8);609 Known = DAG->computeKnownBits(OpMVNIshift4Vec16);610 EXPECT_EQ(Known.Zero, APInt(16, 0xA500));611 EXPECT_EQ(Known.One, APInt(16, 0x5AFF));612 613 auto OpMVNIshift8Vec16 =614 DAG->getNode(AArch64ISD::MVNIshift, Loc, Int8Vec16VT, N165, N0);615 Known = DAG->computeKnownBits(OpMVNIshift8Vec16);616 EXPECT_EQ(Known.Zero, APInt(16, 0x00A5));617 EXPECT_EQ(Known.One, APInt(16, 0xFF5A));618 619 auto FrMVNIshift8Vec16 = DAG->getFreeze(OpMVNIshift8Vec16);620 Known = DAG->computeKnownBits(FrMVNIshift8Vec16);621 EXPECT_EQ(Known.Zero, APInt(16, 0x00A5));622 EXPECT_EQ(Known.One, APInt(16, 0xFF5A));623 624 auto OpMOVI8Vec8 = DAG->getNode(AArch64ISD::MOVI, Loc, Int8Vec8VT, N165);625 Known = DAG->computeKnownBits(OpMOVI8Vec8);626 EXPECT_EQ(Known.Zero, APInt(8, 0x5A));627 EXPECT_EQ(Known.One, APInt(8, 0xA5));628 629 auto OpMOVI16Vec8 = DAG->getNode(AArch64ISD::MOVI, Loc, Int16Vec8VT, N165);630 Known = DAG->computeKnownBits(OpMOVI16Vec8);631 EXPECT_EQ(Known.Zero, APInt(8, 0x5A));632 EXPECT_EQ(Known.One, APInt(8, 0xA5));633 634 auto FrMOVI16Vec8 = DAG->getFreeze(OpMOVI16Vec8);635 Known = DAG->computeKnownBits(FrMOVI16Vec8);636 EXPECT_EQ(Known.Zero, APInt(8, 0x5A));637 EXPECT_EQ(Known.One, APInt(8, 0xA5));638}639 640// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.641TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {642 SDLoc Loc;643 auto IntVT = EVT::getIntegerVT(Context, 8);644 auto N0 = DAG->getConstant(0x55, Loc, IntVT);645 auto UnknownOp = DAG->getRegister(0, IntVT);646 auto Mask = DAG->getConstant(0x2e, Loc, IntVT);647 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask, UnknownOp);648 auto Op = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);649 // N0 = 01010101650 // N1 = 00?0???0651 // =>652 // Known.One = 00000001 (0x1)653 // Known.Zero = 10000000 (0x80)654 KnownBits Known = DAG->computeKnownBits(Op);655 EXPECT_EQ(Known.Zero, APInt(8, 0x80));656 EXPECT_EQ(Known.One, APInt(8, 0x1));657}658 659// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.660TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {661 SDLoc Loc;662 auto IntVT = EVT::getIntegerVT(Context, 8);663 auto N0 = DAG->getConstant(0x5a, Loc, IntVT);664 auto UnknownOp = DAG->getRegister(0, IntVT); // ????????665 auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000666 auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000667 // N1 = (???????? & 00001000) | 00100000 = 0010?000668 auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp);669 N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);670 671 KnownBits Known;672 673 auto UnknownBorrow = DAG->getRegister(1, IntVT);674 auto OpUnknownBorrow =675 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownBorrow);676 // N0 = 01011010677 // N1 = 0010?000678 // B = ?679 // =>680 // Known.Zero = 11000100 (0xc4)681 // Known.One = 00110000 (0x30)682 Known = DAG->computeKnownBits(OpUnknownBorrow);683 EXPECT_EQ(Known.Zero, APInt(8, 0xc4));684 EXPECT_EQ(Known.One, APInt(8, 0x30));685 686 auto ZeroBorrow = DAG->getConstant(0x0, Loc, IntVT);687 auto OpZeroBorrow =688 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, ZeroBorrow);689 // N0 = 01011010690 // N1 = 0010?000691 // B = 0692 // =>693 // Known.Zero = 11000101 (0xc5)694 // Known.One = 00110010 (0x32)695 Known = DAG->computeKnownBits(OpZeroBorrow);696 EXPECT_EQ(Known.Zero, APInt(8, 0xc5));697 EXPECT_EQ(Known.One, APInt(8, 0x32));698 699 auto OneBorrow = DAG->getConstant(0x1, Loc, IntVT);700 auto OpOneBorrow =701 DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, OneBorrow);702 // N0 = 01011010703 // N1 = 0010?000704 // B = 1705 // =>706 // Known.Zero = 11000110 (0xc6)707 // Known.One = 00110001 (0x31)708 Known = DAG->computeKnownBits(OpOneBorrow);709 EXPECT_EQ(Known.Zero, APInt(8, 0xc6));710 EXPECT_EQ(Known.One, APInt(8, 0x31));711}712 713// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.714TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_VASHR) {715 SDLoc Loc;716 KnownBits Known;717 auto VecVT = MVT::v8i8;718 auto Shift0 = DAG->getConstant(4, Loc, MVT::i32);719 auto Vec0 = DAG->getConstant(0x80, Loc, VecVT);720 auto Op0 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, Vec0, Shift0);721 Known = DAG->computeKnownBits(Op0);722 EXPECT_EQ(Known.Zero, APInt(8, 0x07));723 EXPECT_EQ(Known.One, APInt(8, 0xF8));724 725 auto Shift1 = DAG->getConstant(7, Loc, MVT::i32);726 auto Vec1 = DAG->getConstant(0xF7, Loc, VecVT);727 auto Op1 = DAG->getNode(AArch64ISD::VASHR, Loc, VecVT, Vec1, Shift1);728 Known = DAG->computeKnownBits(Op1);729 EXPECT_EQ(Known.Zero, APInt(8, 0x00));730 EXPECT_EQ(Known.One, APInt(8, 0xFF));731 732 auto Fr1 = DAG->getFreeze(Op1);733 Known = DAG->computeKnownBits(Fr1);734 EXPECT_EQ(Known.Zero, APInt(8, 0x00));735 EXPECT_EQ(Known.One, APInt(8, 0xFF));736}737 738// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.739TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_VLSHR) {740 SDLoc Loc;741 KnownBits Known;742 auto VecVT = MVT::v8i8;743 auto Shift0 = DAG->getConstant(4, Loc, MVT::i32);744 auto Vec0 = DAG->getConstant(0x80, Loc, VecVT);745 auto Op0 = DAG->getNode(AArch64ISD::VLSHR, Loc, VecVT, Vec0, Shift0);746 Known = DAG->computeKnownBits(Op0);747 EXPECT_EQ(Known.Zero, APInt(8, 0xF7));748 EXPECT_EQ(Known.One, APInt(8, 0x08));749 750 auto Shift1 = DAG->getConstant(7, Loc, MVT::i32);751 auto Vec1 = DAG->getConstant(0xF7, Loc, VecVT);752 auto Op1 = DAG->getNode(AArch64ISD::VLSHR, Loc, VecVT, Vec1, Shift1);753 Known = DAG->computeKnownBits(Op1);754 EXPECT_EQ(Known.Zero, APInt(8, 0xFE));755 EXPECT_EQ(Known.One, APInt(8, 0x1));756 757 auto Fr1 = DAG->getFreeze(Op1);758 Known = DAG->computeKnownBits(Fr1);759 EXPECT_EQ(Known.Zero, APInt(8, 0xFE));760 EXPECT_EQ(Known.One, APInt(8, 0x1));761}762 763// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.764TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_VSHL) {765 SDLoc Loc;766 KnownBits Known;767 auto VecVT = MVT::v8i8;768 auto Shift0 = DAG->getConstant(4, Loc, MVT::i32);769 auto Vec0 = DAG->getConstant(0x02, Loc, VecVT);770 auto Op0 = DAG->getNode(AArch64ISD::VSHL, Loc, VecVT, Vec0, Shift0);771 Known = DAG->computeKnownBits(Op0);772 EXPECT_EQ(Known.Zero, APInt(8, 0xDF));773 EXPECT_EQ(Known.One, APInt(8, 0x20));774 775 auto Shift1 = DAG->getConstant(7, Loc, MVT::i32);776 auto Vec1 = DAG->getConstant(0xF7, Loc, VecVT);777 auto Op1 = DAG->getNode(AArch64ISD::VSHL, Loc, VecVT, Vec1, Shift1);778 Known = DAG->computeKnownBits(Op1);779 EXPECT_EQ(Known.Zero, APInt(8, 0x7F));780 EXPECT_EQ(Known.One, APInt(8, 0x80));781 782 auto Fr1 = DAG->getFreeze(Op1);783 Known = DAG->computeKnownBits(Fr1);784 EXPECT_EQ(Known.Zero, APInt(8, 0x7F));785 EXPECT_EQ(Known.One, APInt(8, 0x80));786}787 788TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {789 TargetLowering TL(*TM, *STI);790 791 SDLoc Loc;792 auto IntVT = EVT::getIntegerVT(Context, 8);793 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);794 // Create a BUILD_VECTOR795 SDValue Op = DAG->getConstant(1, Loc, VecVT);796 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);797 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));798 799 APInt UndefElts;800 APInt DemandedElts;801 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));802 803 // Width=16, Mask=3804 DemandedElts = APInt(16, 3);805 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));806}807 808TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_ADD_of_BUILD_VECTOR) {809 TargetLowering TL(*TM, *STI);810 811 SDLoc Loc;812 auto IntVT = EVT::getIntegerVT(Context, 8);813 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);814 815 // Should create BUILD_VECTORs816 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);817 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);818 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);819 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);820 821 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));822 823 APInt UndefElts;824 APInt DemandedElts;825 EXPECT_FALSE(DAG->isSplatValue(Op, DemandedElts, UndefElts));826 827 // Width=16, Mask=3828 DemandedElts = APInt(16, 3);829 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));830}831 832TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_SPLAT_VECTOR) {833 TargetLowering TL(*TM, *STI);834 835 SDLoc Loc;836 auto IntVT = EVT::getIntegerVT(Context, 8);837 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);838 // Create a SPLAT_VECTOR839 SDValue Op = DAG->getConstant(1, Loc, VecVT);840 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);841 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));842 843 APInt UndefElts;844 APInt DemandedElts(1, 1);845 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));846}847 848TEST_F(AArch64SelectionDAGTest, isSplatValue_Scalable_ADD_of_SPLAT_VECTOR) {849 TargetLowering TL(*TM, *STI);850 851 SDLoc Loc;852 auto IntVT = EVT::getIntegerVT(Context, 8);853 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);854 855 // Should create SPLAT_VECTORS856 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);857 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);858 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);859 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);860 861 EXPECT_TRUE(DAG->isSplatValue(Op, /*AllowUndefs=*/false));862 863 APInt UndefElts;864 APInt DemandedElts(1, 1);865 EXPECT_TRUE(DAG->isSplatValue(Op, DemandedElts, UndefElts));866}867 868TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Fixed_BUILD_VECTOR) {869 TargetLowering TL(*TM, *STI);870 871 SDLoc Loc;872 auto IntVT = EVT::getIntegerVT(Context, 8);873 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);874 // Create a BUILD_VECTOR875 SDValue Op = DAG->getConstant(1, Loc, VecVT);876 EXPECT_EQ(Op->getOpcode(), ISD::BUILD_VECTOR);877 878 int SplatIdx = -1;879 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);880 EXPECT_EQ(SplatIdx, 0);881}882 883TEST_F(AArch64SelectionDAGTest,884 getSplatSourceVector_Fixed_ADD_of_BUILD_VECTOR) {885 TargetLowering TL(*TM, *STI);886 887 SDLoc Loc;888 auto IntVT = EVT::getIntegerVT(Context, 8);889 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, false);890 891 // Should create BUILD_VECTORs892 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);893 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);894 EXPECT_EQ(Val1->getOpcode(), ISD::BUILD_VECTOR);895 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);896 897 int SplatIdx = -1;898 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);899 EXPECT_EQ(SplatIdx, 0);900}901 902TEST_F(AArch64SelectionDAGTest, getSplatSourceVector_Scalable_SPLAT_VECTOR) {903 TargetLowering TL(*TM, *STI);904 905 SDLoc Loc;906 auto IntVT = EVT::getIntegerVT(Context, 8);907 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);908 // Create a SPLAT_VECTOR909 SDValue Op = DAG->getConstant(1, Loc, VecVT);910 EXPECT_EQ(Op->getOpcode(), ISD::SPLAT_VECTOR);911 912 int SplatIdx = -1;913 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);914 EXPECT_EQ(SplatIdx, 0);915}916 917TEST_F(AArch64SelectionDAGTest,918 getSplatSourceVector_Scalable_ADD_of_SPLAT_VECTOR) {919 TargetLowering TL(*TM, *STI);920 921 SDLoc Loc;922 auto IntVT = EVT::getIntegerVT(Context, 8);923 auto VecVT = EVT::getVectorVT(Context, IntVT, 16, true);924 925 // Should create SPLAT_VECTORS926 SDValue Val1 = DAG->getConstant(1, Loc, VecVT);927 SDValue Val2 = DAG->getConstant(3, Loc, VecVT);928 EXPECT_EQ(Val1->getOpcode(), ISD::SPLAT_VECTOR);929 SDValue Op = DAG->getNode(ISD::ADD, Loc, VecVT, Val1, Val2);930 931 int SplatIdx = -1;932 EXPECT_EQ(DAG->getSplatSourceVector(Op, SplatIdx), Op);933 EXPECT_EQ(SplatIdx, 0);934}935 936TEST_F(AArch64SelectionDAGTest, getRepeatedSequence_Patterns) {937 TargetLowering TL(*TM, *STI);938 939 SDLoc Loc;940 unsigned NumElts = 16;941 MVT IntVT = MVT::i8;942 MVT VecVT = MVT::getVectorVT(IntVT, NumElts);943 944 // Base scalar constants.945 SDValue Val0 = DAG->getConstant(0, Loc, IntVT);946 SDValue Val1 = DAG->getConstant(1, Loc, IntVT);947 SDValue Val2 = DAG->getConstant(2, Loc, IntVT);948 SDValue Val3 = DAG->getConstant(3, Loc, IntVT);949 SDValue UndefVal = DAG->getUNDEF(IntVT);950 951 // Build some repeating sequences.952 SmallVector<SDValue, 16> Pattern1111, Pattern1133, Pattern0123;953 for (int I = 0; I != 4; ++I) {954 Pattern1111.append(4, Val1);955 Pattern1133.append(2, Val1);956 Pattern1133.append(2, Val3);957 Pattern0123.push_back(Val0);958 Pattern0123.push_back(Val1);959 Pattern0123.push_back(Val2);960 Pattern0123.push_back(Val3);961 }962 963 // Build a non-pow2 repeating sequence.964 SmallVector<SDValue, 16> Pattern022;965 Pattern022.push_back(Val0);966 Pattern022.append(2, Val2);967 Pattern022.push_back(Val0);968 Pattern022.append(2, Val2);969 Pattern022.push_back(Val0);970 Pattern022.append(2, Val2);971 Pattern022.push_back(Val0);972 Pattern022.append(2, Val2);973 Pattern022.push_back(Val0);974 Pattern022.append(2, Val2);975 Pattern022.push_back(Val0);976 977 // Build a non-repeating sequence.978 SmallVector<SDValue, 16> Pattern1_3;979 Pattern1_3.append(8, Val1);980 Pattern1_3.append(8, Val3);981 982 // Add some undefs to make it trickier.983 Pattern1111[1] = Pattern1111[2] = Pattern1111[15] = UndefVal;984 Pattern1133[0] = Pattern1133[2] = UndefVal;985 986 auto *BV1111 =987 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1111));988 auto *BV1133 =989 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1133));990 auto *BV0123 =991 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern0123));992 auto *BV022 =993 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern022));994 auto *BV1_3 =995 cast<BuildVectorSDNode>(DAG->getBuildVector(VecVT, Loc, Pattern1_3));996 997 // Check for sequences.998 SmallVector<SDValue, 16> Seq1111, Seq1133, Seq0123, Seq022, Seq1_3;999 BitVector Undefs1111, Undefs1133, Undefs0123, Undefs022, Undefs1_3;1000 1001 EXPECT_TRUE(BV1111->getRepeatedSequence(Seq1111, &Undefs1111));1002 EXPECT_EQ(Undefs1111.count(), 3u);1003 EXPECT_EQ(Seq1111.size(), 1u);1004 EXPECT_EQ(Seq1111[0], Val1);1005 1006 EXPECT_TRUE(BV1133->getRepeatedSequence(Seq1133, &Undefs1133));1007 EXPECT_EQ(Undefs1133.count(), 2u);1008 EXPECT_EQ(Seq1133.size(), 4u);1009 EXPECT_EQ(Seq1133[0], Val1);1010 EXPECT_EQ(Seq1133[1], Val1);1011 EXPECT_EQ(Seq1133[2], Val3);1012 EXPECT_EQ(Seq1133[3], Val3);1013 1014 EXPECT_TRUE(BV0123->getRepeatedSequence(Seq0123, &Undefs0123));1015 EXPECT_EQ(Undefs0123.count(), 0u);1016 EXPECT_EQ(Seq0123.size(), 4u);1017 EXPECT_EQ(Seq0123[0], Val0);1018 EXPECT_EQ(Seq0123[1], Val1);1019 EXPECT_EQ(Seq0123[2], Val2);1020 EXPECT_EQ(Seq0123[3], Val3);1021 1022 EXPECT_FALSE(BV022->getRepeatedSequence(Seq022, &Undefs022));1023 EXPECT_FALSE(BV1_3->getRepeatedSequence(Seq1_3, &Undefs1_3));1024 1025 // Try again with DemandedElts masks.1026 APInt Mask1111_0 = APInt::getOneBitSet(NumElts, 0);1027 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_0, Seq1111, &Undefs1111));1028 EXPECT_EQ(Undefs1111.count(), 0u);1029 EXPECT_EQ(Seq1111.size(), 1u);1030 EXPECT_EQ(Seq1111[0], Val1);1031 1032 APInt Mask1111_1 = APInt::getOneBitSet(NumElts, 2);1033 EXPECT_TRUE(BV1111->getRepeatedSequence(Mask1111_1, Seq1111, &Undefs1111));1034 EXPECT_EQ(Undefs1111.count(), 1u);1035 EXPECT_EQ(Seq1111.size(), 1u);1036 EXPECT_EQ(Seq1111[0], UndefVal);1037 1038 APInt Mask0123 = APInt(NumElts, 0x7777);1039 EXPECT_TRUE(BV0123->getRepeatedSequence(Mask0123, Seq0123, &Undefs0123));1040 EXPECT_EQ(Undefs0123.count(), 0u);1041 EXPECT_EQ(Seq0123.size(), 4u);1042 EXPECT_EQ(Seq0123[0], Val0);1043 EXPECT_EQ(Seq0123[1], Val1);1044 EXPECT_EQ(Seq0123[2], Val2);1045 EXPECT_EQ(Seq0123[3], SDValue());1046 1047 APInt Mask1_3 = APInt::getHighBitsSet(16, 8);1048 EXPECT_TRUE(BV1_3->getRepeatedSequence(Mask1_3, Seq1_3, &Undefs1_3));1049 EXPECT_EQ(Undefs1_3.count(), 0u);1050 EXPECT_EQ(Seq1_3.size(), 1u);1051 EXPECT_EQ(Seq1_3[0], Val3);1052}1053 1054TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableMVT) {1055 MVT VT = MVT::nxv4i64;1056 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);1057 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());1058}1059 1060TEST_F(AArch64SelectionDAGTest, getTypeConversion_PromoteScalableMVT) {1061 MVT VT = MVT::nxv2i32;1062 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypePromoteInteger);1063 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());1064}1065 1066TEST_F(AArch64SelectionDAGTest, getTypeConversion_NoScalarizeMVT_nxv1f32) {1067 MVT VT = MVT::nxv1f32;1068 EXPECT_NE(getTypeAction(VT), TargetLoweringBase::TypeScalarizeVector);1069 ASSERT_TRUE(getTypeToTransformTo(VT).isScalableVector());1070}1071 1072TEST_F(AArch64SelectionDAGTest, getTypeConversion_SplitScalableEVT) {1073 EVT VT = EVT::getVectorVT(Context, MVT::i64, 256, true);1074 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeSplitVector);1075 EXPECT_EQ(getTypeToTransformTo(VT), VT.getHalfNumVectorElementsVT(Context));1076}1077 1078TEST_F(AArch64SelectionDAGTest, getTypeConversion_WidenScalableEVT) {1079 EVT FromVT = EVT::getVectorVT(Context, MVT::i64, 6, true);1080 EVT ToVT = EVT::getVectorVT(Context, MVT::i64, 8, true);1081 1082 EXPECT_EQ(getTypeAction(FromVT), TargetLoweringBase::TypeWidenVector);1083 EXPECT_EQ(getTypeToTransformTo(FromVT), ToVT);1084}1085 1086TEST_F(AArch64SelectionDAGTest,1087 getTypeConversion_ScalarizeScalableEVT_nxv1f128) {1088 EVT VT = EVT::getVectorVT(Context, MVT::f128, ElementCount::getScalable(1));1089 EXPECT_EQ(getTypeAction(VT), TargetLoweringBase::TypeScalarizeScalableVector);1090 EXPECT_EQ(getTypeToTransformTo(VT), MVT::f128);1091}1092 1093TEST_F(AArch64SelectionDAGTest, TestFold_STEP_VECTOR) {1094 SDLoc Loc;1095 auto IntVT = EVT::getIntegerVT(Context, 8);1096 auto VecVT = EVT::getVectorVT(Context, MVT::i8, 16, true);1097 1098 // Should create SPLAT_VECTOR1099 SDValue Zero = DAG->getConstant(0, Loc, IntVT);1100 SDValue Op = DAG->getNode(ISD::STEP_VECTOR, Loc, VecVT, Zero);1101 EXPECT_EQ(Op.getOpcode(), ISD::SPLAT_VECTOR);1102}1103 1104TEST_F(AArch64SelectionDAGTest, ReplaceAllUsesWith) {1105 SDLoc Loc;1106 EVT IntVT = EVT::getIntegerVT(Context, 8);1107 1108 SDValue N0 = DAG->getConstant(0x42, Loc, IntVT);1109 SDValue N1 = DAG->getRegister(0, IntVT);1110 // Construct node to fill arbitrary ExtraInfo.1111 SDValue N2 = DAG->getNode(ISD::SUB, Loc, IntVT, N0, N1);1112 EXPECT_FALSE(DAG->getHeapAllocSite(N2.getNode()));1113 EXPECT_FALSE(DAG->getNoMergeSiteInfo(N2.getNode()));1114 EXPECT_FALSE(DAG->getPCSections(N2.getNode()));1115 MDNode *MD = MDNode::get(Context, {});1116 DAG->addHeapAllocSite(N2.getNode(), MD);1117 DAG->addNoMergeSiteInfo(N2.getNode(), true);1118 DAG->addPCSections(N2.getNode(), MD);1119 EXPECT_EQ(DAG->getHeapAllocSite(N2.getNode()), MD);1120 EXPECT_TRUE(DAG->getNoMergeSiteInfo(N2.getNode()));1121 EXPECT_EQ(DAG->getPCSections(N2.getNode()), MD);1122 1123 SDValue Root = DAG->getNode(ISD::ADD, Loc, IntVT, N2, N2);1124 EXPECT_EQ(Root->getOperand(0)->getOpcode(), ISD::SUB);1125 // Create new node and check that ExtraInfo is propagated on RAUW.1126 SDValue New = DAG->getNode(ISD::ADD, Loc, IntVT, N1, N1);1127 EXPECT_FALSE(DAG->getHeapAllocSite(New.getNode()));1128 EXPECT_FALSE(DAG->getNoMergeSiteInfo(New.getNode()));1129 EXPECT_FALSE(DAG->getPCSections(New.getNode()));1130 1131 DAG->ReplaceAllUsesWith(N2, New);1132 EXPECT_EQ(Root->getOperand(0), New);1133 EXPECT_EQ(DAG->getHeapAllocSite(New.getNode()), MD);1134 EXPECT_TRUE(DAG->getNoMergeSiteInfo(New.getNode()));1135 EXPECT_EQ(DAG->getPCSections(New.getNode()), MD);1136}1137 1138TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_known01) {1139 SDLoc Loc;1140 auto Int8VT = EVT::getIntegerVT(Context, 8);1141 auto Int32VT = EVT::getIntegerVT(Context, 32);1142 auto Int64VT = EVT::getIntegerVT(Context, 64);1143 auto Ptr = DAG->getConstant(0, Loc, Int64VT);1144 auto PtrInfo =1145 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);1146 AAMDNodes AA;1147 MDBuilder MDHelper(*DAG->getContext());1148 MDNode *Range = MDHelper.createRange(APInt(8, 0), APInt(8, 2));1149 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(1150 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);1151 1152 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1153 Ptr, Int8VT, MMO);1154 KnownBits Known = DAG->computeKnownBits(ALoad);1155 EXPECT_EQ(Known.Zero, APInt(32, 0xfe));1156 EXPECT_EQ(Known.One, APInt(32, 0));1157 1158 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1159 Ptr, Int8VT, MMO);1160 Known = DAG->computeKnownBits(ZLoad);1161 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));1162 EXPECT_EQ(Known.One, APInt(32, 0));1163 1164 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1165 Ptr, Int8VT, MMO);1166 Known = DAG->computeKnownBits(SLoad);1167 EXPECT_EQ(Known.Zero, APInt(32, 0xfffffffe));1168 EXPECT_EQ(Known.One, APInt(32, 0));1169}1170 1171TEST_F(AArch64SelectionDAGTest, computeKnownBits_extload_knownnegative) {1172 SDLoc Loc;1173 auto Int8VT = EVT::getIntegerVT(Context, 8);1174 auto Int32VT = EVT::getIntegerVT(Context, 32);1175 auto Int64VT = EVT::getIntegerVT(Context, 64);1176 auto Ptr = DAG->getConstant(0, Loc, Int64VT);1177 auto PtrInfo =1178 MachinePointerInfo::getFixedStack(DAG->getMachineFunction(), 0);1179 AAMDNodes AA;1180 MDBuilder MDHelper(*DAG->getContext());1181 MDNode *Range = MDHelper.createRange(APInt(8, 0xf0), APInt(8, 0xff));1182 MachineMemOperand *MMO = DAG->getMachineFunction().getMachineMemOperand(1183 PtrInfo, MachineMemOperand::MOLoad, 8, Align(8), AA, Range);1184 1185 auto ALoad = DAG->getExtLoad(ISD::EXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1186 Ptr, Int8VT, MMO);1187 KnownBits Known = DAG->computeKnownBits(ALoad);1188 EXPECT_EQ(Known.Zero, APInt(32, 0));1189 EXPECT_EQ(Known.One, APInt(32, 0xf0));1190 1191 auto ZLoad = DAG->getExtLoad(ISD::ZEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1192 Ptr, Int8VT, MMO);1193 Known = DAG->computeKnownBits(ZLoad);1194 EXPECT_EQ(Known.Zero, APInt(32, 0xffffff00));1195 EXPECT_EQ(Known.One, APInt(32, 0x000000f0));1196 1197 auto SLoad = DAG->getExtLoad(ISD::SEXTLOAD, Loc, Int32VT, DAG->getEntryNode(),1198 Ptr, Int8VT, MMO);1199 Known = DAG->computeKnownBits(SLoad);1200 EXPECT_EQ(Known.Zero, APInt(32, 0));1201 EXPECT_EQ(Known.One, APInt(32, 0xfffffff0));1202}1203 1204TEST_F(AArch64SelectionDAGTest,1205 computeKnownBits_AVGFLOORU_AVGFLOORS_AVGCEILU_AVGCEILS) {1206 SDLoc Loc;1207 auto Int8VT = EVT::getIntegerVT(Context, 8);1208 auto Int16VT = EVT::getIntegerVT(Context, 16);1209 auto Int8Vec8VT = EVT::getVectorVT(Context, Int8VT, 8);1210 auto Int16Vec8VT = EVT::getVectorVT(Context, Int16VT, 8);1211 1212 SDValue UnknownOp0 = DAG->getRegister(0, Int8Vec8VT);1213 SDValue UnknownOp1 = DAG->getRegister(1, Int8Vec8VT);1214 1215 SDValue ZextOp0 =1216 DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp0);1217 SDValue ZextOp1 =1218 DAG->getNode(ISD::ZERO_EXTEND, Loc, Int16Vec8VT, UnknownOp1);1219 // ZextOp0 = 00000000????????1220 // ZextOp1 = 00000000????????1221 // => (for all AVG* instructions)1222 // Known.Zero = 1111111100000000 (0xFF00)1223 // Known.One = 0000000000000000 (0x0000)1224 auto Zeroes = APInt(16, 0xFF00);1225 auto Ones = APInt(16, 0x0000);1226 1227 SDValue AVGFLOORU =1228 DAG->getNode(ISD::AVGFLOORU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);1229 KnownBits KnownAVGFLOORU = DAG->computeKnownBits(AVGFLOORU);1230 EXPECT_EQ(KnownAVGFLOORU.Zero, Zeroes);1231 EXPECT_EQ(KnownAVGFLOORU.One, Ones);1232 1233 SDValue AVGFLOORS =1234 DAG->getNode(ISD::AVGFLOORS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);1235 KnownBits KnownAVGFLOORS = DAG->computeKnownBits(AVGFLOORS);1236 EXPECT_EQ(KnownAVGFLOORS.Zero, Zeroes);1237 EXPECT_EQ(KnownAVGFLOORS.One, Ones);1238 1239 SDValue AVGCEILU =1240 DAG->getNode(ISD::AVGCEILU, Loc, Int16Vec8VT, ZextOp0, ZextOp1);1241 KnownBits KnownAVGCEILU = DAG->computeKnownBits(AVGCEILU);1242 EXPECT_EQ(KnownAVGCEILU.Zero, Zeroes);1243 EXPECT_EQ(KnownAVGCEILU.One, Ones);1244 1245 SDValue AVGCEILS =1246 DAG->getNode(ISD::AVGCEILS, Loc, Int16Vec8VT, ZextOp0, ZextOp1);1247 KnownBits KnownAVGCEILS = DAG->computeKnownBits(AVGCEILS);1248 EXPECT_EQ(KnownAVGCEILS.Zero, Zeroes);1249 EXPECT_EQ(KnownAVGCEILS.One, Ones);1250}1251 1252} // end namespace llvm1253