brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · c763da9 Raw
198 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 "ARMSelectionDAGInfo.h"9#include "MCTargetDesc/ARMAddressingModes.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 ARMSelectionDAGTest : public testing::Test {27protected:28  static void SetUpTestCase() {29    LLVMInitializeARMTargetInfo();30    LLVMInitializeARMTarget();31    LLVMInitializeARMTargetMC();32  }33 34  void SetUp() override {35    StringRef Assembly = "define void @f() { ret void }";36 37    Triple TargetTriple("armv7-unknown-none-eabi");38 39    std::string Error;40    const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);41 42    TargetOptions Options;43    TM = std::unique_ptr<TargetMachine>(44        T->createTargetMachine(TargetTriple,45                               /*CPU*/ "cortex-a9",46                               /*Features*/ "+neon", Options, std::nullopt,47                               std::nullopt, CodeGenOptLevel::Aggressive));48 49    SMDiagnostic SMError;50    M = parseAssemblyString(Assembly, SMError, Context);51    if (!M)52      report_fatal_error(SMError.getMessage());53    M->setDataLayout(TM->createDataLayout());54 55    F = M->getFunction("f");56    if (!F)57      report_fatal_error("Function 'f' not found");58 59    MachineModuleInfo MMI(TM.get());60 61    MF = std::make_unique<MachineFunction>(*F, *TM, *TM->getSubtargetImpl(*F),62                                           MMI.getContext(), /*FunctionNum*/ 0);63 64    DAG = std::make_unique<SelectionDAG>(*TM, CodeGenOptLevel::None);65    if (!DAG)66      report_fatal_error("SelectionDAG allocation failed");67 68    OptimizationRemarkEmitter ORE(F);69    DAG->init(*MF, ORE, /*LibInfo*/ nullptr, /*AA*/ nullptr,70              /*AC*/ nullptr, /*MDT*/ nullptr, /*MSDT*/ nullptr, MMI, nullptr);71  }72 73  TargetLoweringBase::LegalizeTypeAction getTypeAction(EVT VT) {74    return DAG->getTargetLoweringInfo().getTypeAction(Context, VT);75  }76 77  EVT getTypeToTransformTo(EVT VT) {78    return DAG->getTargetLoweringInfo().getTypeToTransformTo(Context, VT);79  }80 81  LLVMContext Context;82  std::unique_ptr<TargetMachine> TM;83  std::unique_ptr<Module> M;84  Function *F = nullptr;85  std::unique_ptr<MachineFunction> MF;86  std::unique_ptr<SelectionDAG> DAG;87};88 89/// VORR (immediate): per-lane OR with 32-bit elements.90/// cmode=0x0 puts imm8 in byte0 => per-lane constant = 0x000000AA.91TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM) {92  SDLoc DL;93  EVT VT = MVT::v4i32;94  SDValue LHS = DAG->getRegister(0, VT);95 96  SDValue EncSD =97      DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);98  SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);99 100  // LHS(per-lane)     = ???????? ???????? ???????? ????????101  // Encoded(per-lane) = 00000000 00000000 00000000 10101010  (0x000000AA)102  //  =>103  // Known.One  = 00000000 00000000 00000000 10101010  (0x000000AA)104  // Known.Zero = 00000000 00000000 00000000 00000000  (0x00000000)105  APInt DemandedElts = APInt::getAllOnes(4);106  KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);107  EXPECT_EQ(Known.One, APInt(32, 0xAA));108  EXPECT_EQ(Known.Zero, APInt(32, 0x0));109 110  // LHS(per-lane)     = 00000000 00000000 00000000 00000000  (0x00000000)111  // Encoded(per-lane) = 00000000 00000000 00000000 10101010  (0x000000AA)112  //  =>113  // Known.One  = 00000000 00000000 00000000 10101010  (0x000000AA)114  // Known.Zero = 11111111 11111111 11111111 01010101  (0x00000000)115  SDValue Zero = DAG->getConstant(0, DL, MVT::i32);116  SDValue ZeroVec = DAG->getSplatBuildVector(VT, DL, Zero);117  Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, ZeroVec, EncSD);118  SDValue FrVORRIMM = DAG->getFreeze(Op);119  Known = DAG->computeKnownBits(FrVORRIMM);120  EXPECT_EQ(Known.One, APInt(32, 0xAA));121  EXPECT_EQ(Known.Zero, APInt(32, 0xFFFFFF55));122}123 124/// VBIC (immediate): x & ~imm with 32-bit elements.125/// LHS(per-lane)=0xFFFFFFFF; imm per-lane = 0x000000AA => result = 0xFFFFFF55126TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM) {127  SDLoc DL;128  EVT VT = MVT::v4i32;129 130  SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);131 132  SDValue EncSD =133      DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x0, 0xAA), DL, MVT::i32);134  SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);135 136  // LHS(per-lane)     = 11111111 11111111 11111111 11111111  (0xFFFFFFFF)137  // Encoded(per-lane) = 00000000 00000000 00000000 10101010  (0x000000AA)138  //  =>139  // Known.One  = 11111111 11111111 11111111 01010101  (0xFFFFFF55)140  // Known.Zero = 00000000 00000000 00000000 10101010  (0x000000AA)141  APInt DemandedElts = APInt::getAllOnes(4);142  KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);143  EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));144  EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));145 146  SDValue FrVBICIMM = DAG->getFreeze(Op);147  Known = DAG->computeKnownBits(FrVBICIMM);148  EXPECT_EQ(Known.One, APInt(32, 0xFFFFFF55));149  EXPECT_EQ(Known.Zero, APInt(32, 0x000000AA));150}151 152/// VORR (immediate): per-lane OR with 32-bit elements.153/// Encoded = 0x2AA (cmode=0x2, imm8=0xAA) => per-lane constant = 0x0000AA00.154TEST_F(ARMSelectionDAGTest, computeKnownBits_VORRIMM_cmode2) {155  SDLoc DL;156  EVT VT = MVT::v4i32;157  SDValue LHS = DAG->getRegister(0, VT);158 159  // Use the exact encoded immediate the reviewer asked for.160  SDValue EncSD =161      DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x2, 0xAA), DL, MVT::i32);162  SDValue Op = DAG->getNode(ARMISD::VORRIMM, DL, VT, LHS, EncSD);163 164  // LHS (per-lane)     = ???????? ???????? ???????? ????????165  // Encoded (per-lane) = 00000000 00000000 10101010 00000000  (0x0000AA00)166  //  =>167  // Known.One          = 00000000 00000000 10101010 00000000  (0x0000AA00)168  // Known.Zero         = 00000000 00000000 00000000 00000000  (0x00000000)169  APInt DemandedElts = APInt::getAllOnes(4);170  KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);171  EXPECT_EQ(Known.One, APInt(32, 0x0000AA00));172  EXPECT_EQ(Known.Zero, APInt(32, 0x00000000));173}174 175/// VBIC (immediate) with constant-all-ones LHS:176/// Encoded = 0x2AA => per-lane constant = 0x0000AA00; VBIC = A & ~Imm.177TEST_F(ARMSelectionDAGTest, computeKnownBits_VBICIMM_cmode2_lhs_ones) {178  SDLoc DL;179  EVT VT = MVT::v4i32;180 181  SDValue LHS = DAG->getConstant(APInt(32, 0xFFFFFFFF), DL, VT);182  SDValue EncSD =183      DAG->getTargetConstant(ARM_AM::createVMOVModImm(0x2, 0xAA), DL, MVT::i32);184  SDValue Op = DAG->getNode(ARMISD::VBICIMM, DL, VT, LHS, EncSD);185 186  // LHS (per-lane)     = 11111111 11111111 11111111 11111111187  // Encoded (per-lane) = 00000000 00000000 10101010 00000000  (0x0000AA00)188  //  =>189  // Known.One          = 11111111 11111111 01010101 11111111  (0xFFFF55FF)190  // Known.Zero         = 00000000 00000000 10101010 00000000  (0x0000AA00)191  APInt DemandedElts = APInt::getAllOnes(4);192  KnownBits Known = DAG->computeKnownBits(Op, DemandedElts);193  EXPECT_EQ(Known.One, APInt(32, 0xFFFF55FF));194  EXPECT_EQ(Known.Zero, APInt(32, 0x0000AA00));195}196 197} // end namespace llvm198