brintos

brintos / llvm-project-archived public Read only

0
0
Text · 44.7 KiB · 14e1efa Raw
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