4279 lines · cpp
1//===- LegalizerHelperTest.cpp2//-----------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#include "GISelMITest.h"11#include "llvm/CodeGen/GlobalISel/LostDebugLocObserver.h"12 13using namespace LegalizeActions;14using namespace LegalizeMutations;15using namespace LegalityPredicates;16 17namespace {18 19class DummyGISelObserver : public GISelChangeObserver {20public:21 void changingInstr(MachineInstr &MI) override {}22 void changedInstr(MachineInstr &MI) override {}23 void createdInstr(MachineInstr &MI) override {}24 void erasingInstr(MachineInstr &MI) override {}25};26 27// Test G_ROTL/G_ROTR lowering.28TEST_F(AArch64GISelMITest, LowerRotates) {29 setUp();30 if (!TM)31 GTEST_SKIP();32 33 // Declare your legalization info34 DefineLegalizerInfo(A, {35 getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });36 37 LLT S32 = LLT::scalar(32);38 auto Src = B.buildTrunc(S32, Copies[0]);39 auto Amt = B.buildTrunc(S32, Copies[1]);40 auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {S32}, {Src, Amt});41 auto ROTL = B.buildInstr(TargetOpcode::G_ROTL, {S32}, {Src, Amt});42 43 AInfo Info(MF->getSubtarget());44 DummyGISelObserver Observer;45 LegalizerHelper Helper(*MF, Info, Observer, B);46 // Perform Legalization47 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,48 Helper.lower(*ROTR, 0, S32));49 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,50 Helper.lower(*ROTL, 0, S32));51 52 auto CheckStr = R"(53 ; Check G_ROTR54 CHECK: [[SRC:%[0-9]+]]:_(s32) = G_TRUNC55 CHECK: [[AMT:%[0-9]+]]:_(s32) = G_TRUNC56 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 057 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3158 CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_59 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_60 CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND]]:_(s32)61 CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_62 CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND1]]:_(s32)63 CHECK: G_OR [[LSHR]]:_, [[SHL]]:_64 65 ; Check G_ROTL66 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 067 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 3168 CHECK: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[C]]:_, [[AMT]]:_69 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[AMT]]:_, [[C1]]:_70 CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[SRC]]:_, [[AND]]:_(s32)71 CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[SUB]]:_, [[C1]]:_72 CHECK: [[LSHR:%[0-9]+]]:_(s32) = G_LSHR [[SRC]]:_, [[AND1]]:_(s32)73 CHECK: G_OR [[SHL]]:_, [[LSHR]]:_74 )";75 76 // Check77 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;78}79 80// Test G_ROTL/G_ROTR non-pow2 lowering.81TEST_F(AArch64GISelMITest, LowerRotatesNonPow2) {82 setUp();83 if (!TM)84 GTEST_SKIP();85 86 // Declare your legalization info87 DefineLegalizerInfo(A, {88 getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });89 90 LLT S24 = LLT::scalar(24);91 auto Src = B.buildTrunc(S24, Copies[0]);92 auto Amt = B.buildTrunc(S24, Copies[1]);93 auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {S24}, {Src, Amt});94 auto ROTL = B.buildInstr(TargetOpcode::G_ROTL, {S24}, {Src, Amt});95 96 AInfo Info(MF->getSubtarget());97 DummyGISelObserver Observer;98 LegalizerHelper Helper(*MF, Info, Observer, B);99 // Perform Legalization100 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,101 Helper.lower(*ROTR, 0, S24));102 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,103 Helper.lower(*ROTL, 0, S24));104 105 auto CheckStr = R"(106 ; Check G_ROTR107 CHECK: [[SRC:%[0-9]+]]:_(s24) = G_TRUNC108 CHECK: [[AMT:%[0-9]+]]:_(s24) = G_TRUNC109 CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0110 CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23111 CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24112 CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_113 CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[UREM]]:_(s24)114 CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_115 CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1116 CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[C4]]:_(s24)117 CHECK: [[SHL2:%[0-9]+]]:_(s24) = G_SHL [[SHL]]:_, [[SUB]]:_(s24)118 CHECK: G_OR [[LSHR]]:_, [[SHL2]]:_119 120 ; Check G_ROTL121 CHECK: [[C:%[0-9]+]]:_(s24) = G_CONSTANT i24 0122 CHECK: [[C1:%[0-9]+]]:_(s24) = G_CONSTANT i24 23123 CHECK: [[C2:%[0-9]+]]:_(s24) = G_CONSTANT i24 24124 CHECK: [[UREM:%[0-9]+]]:_(s24) = G_UREM [[AMT]]:_, [[C2]]:_125 CHECK: [[SHL:%[0-9]+]]:_(s24) = G_SHL [[SRC]]:_, [[UREM]]:_(s24)126 CHECK: [[SUB:%[0-9]+]]:_(s24) = G_SUB [[C1]]:_, [[UREM]]:_127 CHECK: [[C4:%[0-9]+]]:_(s24) = G_CONSTANT i24 1128 CHECK: [[LSHR:%[0-9]+]]:_(s24) = G_LSHR [[SRC]]:_, [[C4]]:_(s24)129 CHECK: [[LSHR2:%[0-9]+]]:_(s24) = G_LSHR [[LSHR]]:_, [[SUB]]:_(s24)130 CHECK: G_OR [[SHL]]:_, [[LSHR2]]:_131 )";132 133 // Check134 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;135}136 137// Test vector G_ROTR lowering.138TEST_F(AArch64GISelMITest, LowerRotatesVector) {139 setUp();140 if (!TM)141 GTEST_SKIP();142 143 // Declare your legalization info144 DefineLegalizerInfo(A, {145 getActionDefinitionsBuilder({G_ROTR, G_ROTL}).lower(); });146 147 LLT S32 = LLT::scalar(32);148 LLT V4S32 = LLT::fixed_vector(4, S32);149 auto SrcTrunc = B.buildTrunc(S32, Copies[0]);150 auto Src = B.buildSplatBuildVector(V4S32, SrcTrunc);151 auto AmtTrunc = B.buildTrunc(S32, Copies[1]);152 auto Amt = B.buildSplatBuildVector(V4S32, AmtTrunc);153 auto ROTR = B.buildInstr(TargetOpcode::G_ROTR, {V4S32}, {Src, Amt});154 155 AInfo Info(MF->getSubtarget());156 DummyGISelObserver Observer;157 LegalizerHelper Helper(*MF, Info, Observer, B);158 // Perform Legalization159 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,160 Helper.lower(*ROTR, 0, V4S32));161 162 auto CheckStr = R"(163 CHECK: [[SRCTRUNC:%[0-9]+]]:_(s32) = G_TRUNC164 CHECK: [[SRC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[SRCTRUNC]]165 CHECK: [[AMTTRUNC:%[0-9]+]]:_(s32) = G_TRUNC166 CHECK: [[AMT:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[AMTTRUNC]]167 CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0168 CHECK: [[ZERO:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]]169 CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 31170 CHECK: [[VEC31:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]]171 CHECK: [[SUB:%[0-9]+]]:_(<4 x s32>) = G_SUB [[ZERO]]:_, [[AMT]]:_172 CHECK: [[AND:%[0-9]+]]:_(<4 x s32>) = G_AND [[AMT]]:_, [[VEC31]]:_173 CHECK: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[SRC]]:_, [[AND]]:_(<4 x s32>)174 CHECK: [[AND1:%[0-9]+]]:_(<4 x s32>) = G_AND [[SUB]]:_, [[VEC31]]:_175 CHECK: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL [[SRC]]:_, [[AND1]]:_(<4 x s32>)176 CHECK: G_OR [[LSHR]]:_, [[SHL]]:_177 )";178 179 // Check180 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;181}182 183// Test CTTZ expansion when CTTZ_ZERO_UNDEF is legal or custom,184// in which case it becomes CTTZ_ZERO_UNDEF with select.185TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ0) {186 setUp();187 if (!TM)188 GTEST_SKIP();189 190 // Declare your legalization info191 DefineLegalizerInfo(A, {192 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s32, s64}});193 });194 // Build Instr195 auto MIBCTTZ =196 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});197 AInfo Info(MF->getSubtarget());198 DummyGISelObserver Observer;199 LegalizerHelper Helper(*MF, Info, Observer, B);200 // Perform Legalization201 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,202 Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)));203 204 auto CheckStr = R"(205 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF %0206 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0207 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]208 CHECK: [[SIXTY4:%[0-9]+]]:_(s32) = G_CONSTANT i32 64209 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]210 )";211 212 // Check213 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;214}215 216// CTTZ expansion in terms of CTLZ217TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ1) {218 setUp();219 if (!TM)220 GTEST_SKIP();221 222 // Declare your legalization info223 DefineLegalizerInfo(A, {224 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s64, s64}});225 });226 // Build Instr227 auto MIBCTTZ =228 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});229 AInfo Info(MF->getSubtarget());230 DummyGISelObserver Observer;231 LegalizerHelper Helper(*MF, Info, Observer, B);232 // Perform Legalization233 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==234 LegalizerHelper::LegalizeResult::Legalized);235 236 auto CheckStr = R"(237 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1238 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]239 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]240 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_241 CHECK: [[CST64:%[0-9]+]]:_(s64) = G_CONSTANT i64 64242 CHECK: [[CTLZ:%[0-9]+]]:_(s64) = G_CTLZ [[AND1]]:_243 CHECK: G_SUB [[CST64]]:_, [[CTLZ]]:_244 )";245 246 // Check247 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;248}249 250// CTLZ scalar narrowing251TEST_F(AArch64GISelMITest, NarrowScalarCTLZ) {252 setUp();253 if (!TM)254 GTEST_SKIP();255 256 // Declare your legalization info257 DefineLegalizerInfo(A, {258 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s32, s32}});259 });260 // Build Instr261 auto CTLZ =262 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});263 AInfo Info(MF->getSubtarget());264 DummyGISelObserver Observer;265 LegalizerHelper Helper(*MF, Info, Observer, B);266 // Perform Legalization267 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,268 Helper.narrowScalar(*CTLZ, 1, LLT::scalar(32)));269 270 auto CheckStr = R"(271 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)272 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0273 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_HI]]:_(s32), [[ZERO]]:_274 CHECK: [[CTLZ_LO:%[0-9]+]]:_(s32) = G_CTLZ [[UNMERGE_LO]]:_(s32)275 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32276 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTLZ_LO]]:_, [[THIRTYTWO]]:_277 CHECK: [[CTLZ_HI:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF [[UNMERGE_HI]]:_(s32)278 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTLZ_HI]]:_279 )";280 281 // Check282 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;283}284 285// CTTZ scalar narrowing286TEST_F(AArch64GISelMITest, NarrowScalarCTTZ) {287 setUp();288 if (!TM)289 GTEST_SKIP();290 291 // Declare your legalization info292 DefineLegalizerInfo(A, {293 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s32, s64}});294 });295 // Build Instr296 auto CTTZ =297 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(32)}, {Copies[0]});298 AInfo Info(MF->getSubtarget());299 DummyGISelObserver Observer;300 LegalizerHelper Helper(*MF, Info, Observer, B);301 // Perform Legalization302 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,303 Helper.narrowScalar(*CTTZ, 1, LLT::scalar(32)));304 305 auto CheckStr = R"(306 CHECK: [[UNMERGE_LO:%[0-9]+]]:_(s32), [[UNMERGE_HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES %0:_(s64)307 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0308 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[UNMERGE_LO]]:_(s32), [[ZERO]]:_309 CHECK: [[CTTZ_HI:%[0-9]+]]:_(s32) = G_CTTZ [[UNMERGE_HI]]:_(s32)310 CHECK: [[THIRTYTWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 32311 CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[CTTZ_HI]]:_, [[THIRTYTWO]]:_312 CHECK: [[CTTZ_LO:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[UNMERGE_LO]]:_(s32)313 CHECK: %{{[0-9]+}}:_(s32) = G_SELECT [[CMP]]:_(s1), [[ADD]]:_, [[CTTZ_LO]]:_314 )";315 316 // Check317 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;318}319 320// CTTZ expansion in terms of CTPOP321TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ2) {322 setUp();323 if (!TM)324 GTEST_SKIP();325 326 // Declare your legalization info327 DefineLegalizerInfo(A, {328 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s64, s64}});329 });330 // Build331 auto MIBCTTZ =332 B.buildInstr(TargetOpcode::G_CTTZ, {LLT::scalar(64)}, {Copies[0]});333 AInfo Info(MF->getSubtarget());334 DummyGISelObserver Observer;335 LegalizerHelper Helper(*MF, Info, Observer, B);336 337 B.setInsertPt(*EntryMBB, MIBCTTZ->getIterator());338 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==339 LegalizerHelper::LegalizeResult::Legalized);340 341 auto CheckStr = R"(342 CHECK: [[NEG1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1343 CHECK: [[NOT:%[0-9]+]]:_(s64) = G_XOR %0:_, [[NEG1]]344 CHECK: [[SUB1:%[0-9]+]]:_(s64) = G_ADD %0:_, [[NEG1]]345 CHECK: [[AND1:%[0-9]+]]:_(s64) = G_AND [[NOT]]:_, [[SUB1]]:_346 CHECK: [[POP:%[0-9]+]]:_(s64) = G_CTPOP [[AND1]]347 )";348 349 // Check350 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;351}352 353// CTPOP widening.354TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP1) {355 setUp();356 if (!TM)357 GTEST_SKIP();358 359 // Declare your legalization info360 DefineLegalizerInfo(A, {361 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});362 });363 364 // Build365 // Trunc it to s8.366 LLT s8{LLT::scalar(8)};367 LLT s16{LLT::scalar(16)};368 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);369 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s16}, {MIBTrunc});370 AInfo Info(MF->getSubtarget());371 DummyGISelObserver Observer;372 LegalizerHelper Helper(*MF, Info, Observer, B);373 B.setInstr(*MIBCTPOP);374 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,375 Helper.widenScalar(*MIBCTPOP, 1, s16));376 377 auto CheckStr = R"(378 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)379 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)380 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]381 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[CTPOP]]:_(s16)382 )";383 384 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;385}386 387// Test a strange case where the result is wider than the source388TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP2) {389 setUp();390 if (!TM)391 GTEST_SKIP();392 393 // Declare your legalization info394 DefineLegalizerInfo(A, {395 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s32, s16}});396 });397 398 // Build399 // Trunc it to s8.400 LLT s8{LLT::scalar(8)};401 LLT s16{LLT::scalar(16)};402 LLT s32{LLT::scalar(32)};403 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);404 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s32}, {MIBTrunc});405 AInfo Info(MF->getSubtarget());406 DummyGISelObserver Observer;407 LegalizerHelper Helper(*MF, Info, Observer, B);408 B.setInstr(*MIBCTPOP);409 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,410 Helper.widenScalar(*MIBCTPOP, 1, s16));411 412 auto CheckStr = R"(413 CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC %0:_(s64)414 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC]]:_(s8)415 CHECK: [[CTPOP:%[0-9]+]]:_(s16) = G_CTPOP [[ZEXT]]416 CHECK: [[COPY:%[0-9]+]]:_(s32) = G_ZEXT [[CTPOP]]:_(s16)417 )";418 419 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;420}421 422// CTTZ_ZERO_UNDEF expansion in terms of CTTZ423TEST_F(AArch64GISelMITest, LowerBitCountingCTTZ3) {424 setUp();425 if (!TM)426 GTEST_SKIP();427 428 // Declare your legalization info429 DefineLegalizerInfo(A, {430 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s64, s64}});431 });432 // Build433 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF,434 {LLT::scalar(64)}, {Copies[0]});435 AInfo Info(MF->getSubtarget());436 DummyGISelObserver Observer;437 LegalizerHelper Helper(*MF, Info, Observer, B);438 EXPECT_TRUE(Helper.lower(*MIBCTTZ, 0, LLT::scalar(64)) ==439 LegalizerHelper::LegalizeResult::Legalized);440 441 auto CheckStr = R"(442 CHECK: CTTZ443 )";444 445 // Check446 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;447}448 449// CTLZ expansion in terms of CTLZ_ZERO_UNDEF450TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ0) {451 setUp();452 if (!TM)453 GTEST_SKIP();454 455 // Declare your legalization info456 DefineLegalizerInfo(A, {457 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s64, s64}});458 });459 // Build460 auto MIBCTLZ =461 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(64)}, {Copies[0]});462 AInfo Info(MF->getSubtarget());463 DummyGISelObserver Observer;464 LegalizerHelper Helper(*MF, Info, Observer, B);465 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, LLT::scalar(64)) ==466 LegalizerHelper::LegalizeResult::Legalized);467 468 auto CheckStr = R"(469 CHECK: [[CZU:%[0-9]+]]:_(s64) = G_CTLZ_ZERO_UNDEF %0470 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0471 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]472 CHECK: [[SIXTY4:%[0-9]+]]:_(s64) = G_CONSTANT i64 64473 CHECK: [[SEL:%[0-9]+]]:_(s64) = G_SELECT [[CMP]]:_(s1), [[SIXTY4]]:_, [[CZU]]474 )";475 476 // Check477 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;478}479 480// CTLZ expansion in terms of CTLZ_ZERO_UNDEF if the latter is a libcall481TEST_F(AArch64GISelMITest, LowerBitCountingCTLZLibcall) {482 setUp();483 if (!TM)484 GTEST_SKIP();485 486 // Declare your legalization info487 DefineLegalizerInfo(A, {488 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).libcallFor({{s32, s64}});489 });490 // Build491 auto MIBCTLZ =492 B.buildInstr(TargetOpcode::G_CTLZ, {LLT::scalar(32)}, {Copies[0]});493 AInfo Info(MF->getSubtarget());494 DummyGISelObserver Observer;495 LegalizerHelper Helper(*MF, Info, Observer, B);496 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,497 Helper.lower(*MIBCTLZ, 0, LLT::scalar(32)));498 499 auto CheckStr = R"(500 CHECK: [[CZU:%[0-9]+]]:_(s32) = G_CTLZ_ZERO_UNDEF %0501 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0502 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %0:_(s64), [[ZERO]]503 CHECK: [[THIRTY2:%[0-9]+]]:_(s32) = G_CONSTANT i32 64504 CHECK: [[SEL:%[0-9]+]]:_(s32) = G_SELECT [[CMP]]:_(s1), [[THIRTY2]]:_, [[CZU]]505 )";506 507 // Check508 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;509}510 511// CTLZ expansion512TEST_F(AArch64GISelMITest, LowerBitCountingCTLZ1) {513 setUp();514 if (!TM)515 GTEST_SKIP();516 517 // Declare your legalization info518 DefineLegalizerInfo(A, {519 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s8, s8}});520 });521 // Build522 // Trunc it to s8.523 LLT s8{LLT::scalar(8)};524 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);525 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});526 AInfo Info(MF->getSubtarget());527 DummyGISelObserver Observer;528 LegalizerHelper Helper(*MF, Info, Observer, B);529 EXPECT_TRUE(Helper.lower(*MIBCTLZ, 0, s8) ==530 LegalizerHelper::LegalizeResult::Legalized);531 532 auto CheckStr = R"(533 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC534 CHECK: [[Cst1:%[0-9]+]]:_(s8) = G_CONSTANT i8 1535 CHECK: [[Sh1:%[0-9]+]]:_(s8) = G_LSHR [[Trunc]]:_, [[Cst1]]:_536 CHECK: [[Or1:%[0-9]+]]:_(s8) = G_OR [[Trunc]]:_, [[Sh1]]:_537 CHECK: [[Cst2:%[0-9]+]]:_(s8) = G_CONSTANT i8 2538 CHECK: [[Sh2:%[0-9]+]]:_(s8) = G_LSHR [[Or1]]:_, [[Cst2]]:_539 CHECK: [[Or2:%[0-9]+]]:_(s8) = G_OR [[Or1]]:_, [[Sh2]]:_540 CHECK: [[Cst4:%[0-9]+]]:_(s8) = G_CONSTANT i8 4541 CHECK: [[Sh4:%[0-9]+]]:_(s8) = G_LSHR [[Or2]]:_, [[Cst4]]:_542 CHECK: [[Or4:%[0-9]+]]:_(s8) = G_OR [[Or2]]:_, [[Sh4]]:_543 CHECK: [[CTPOP:%[0-9]+]]:_(s8) = G_CTPOP [[Or4]]:_544 CHECK: [[Len:%[0-9]+]]:_(s8) = G_CONSTANT i8 8545 CHECK: [[Sub:%[0-9]+]]:_(s8) = G_SUB [[Len]]:_, [[CTPOP]]:_546 )";547 548 // Check549 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;550}551 552// CTLZ widening.553TEST_F(AArch64GISelMITest, WidenBitCountingCTLZ) {554 setUp();555 if (!TM)556 GTEST_SKIP();557 558 // Declare your legalization info559 DefineLegalizerInfo(A, {560 getActionDefinitionsBuilder(G_CTLZ).legalFor({{s16, s16}});561 });562 // Build563 // Trunc it to s8.564 LLT s8{LLT::scalar(8)};565 LLT s16{LLT::scalar(16)};566 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);567 auto MIBCTLZ = B.buildInstr(TargetOpcode::G_CTLZ, {s8}, {MIBTrunc});568 AInfo Info(MF->getSubtarget());569 DummyGISelObserver Observer;570 LegalizerHelper Helper(*MF, Info, Observer, B);571 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ, 1, s16) ==572 LegalizerHelper::LegalizeResult::Legalized);573 574 auto CheckStr = R"(575 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC576 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]577 CHECK: [[Ctlz:%[0-9]+]]:_(s16) = G_CTLZ [[Zext]]578 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8579 CHECK: [[Sub:%[0-9]+]]:_(s16) = G_SUB [[Ctlz]]:_, [[Cst8]]:_580 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Sub]]581 )";582 583 // Check584 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;585}586 587// CTLZ_ZERO_UNDEF widening.588TEST_F(AArch64GISelMITest, WidenBitCountingCTLZZeroUndef) {589 setUp();590 if (!TM)591 GTEST_SKIP();592 593 // Declare your legalization info594 DefineLegalizerInfo(A, {595 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF).legalFor({{s16, s16}});596 });597 // Build598 // Trunc it to s8.599 LLT s8{LLT::scalar(8)};600 LLT s16{LLT::scalar(16)};601 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);602 auto MIBCTLZ_ZU =603 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {s8}, {MIBTrunc});604 AInfo Info(MF->getSubtarget());605 DummyGISelObserver Observer;606 LegalizerHelper Helper(*MF, Info, Observer, B);607 EXPECT_TRUE(Helper.widenScalar(*MIBCTLZ_ZU, 1, s16) ==608 LegalizerHelper::LegalizeResult::Legalized);609 610 auto CheckStr = R"(611 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC612 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]613 CHECK: [[Cst8:%[0-9]+]]:_(s16) = G_CONSTANT i16 8614 CHECK: [[Shl:%[0-9]+]]:_(s16) = G_SHL [[Zext]]:_, [[Cst8]]:_615 CHECK: [[CtlzZu:%[0-9]+]]:_(s16) = G_CTLZ_ZERO_UNDEF [[Shl]]616 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CtlzZu]]617 )";618 619 // Check620 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;621}622 623// CTPOP widening.624TEST_F(AArch64GISelMITest, WidenBitCountingCTPOP) {625 setUp();626 if (!TM)627 GTEST_SKIP();628 629 // Declare your legalization info630 DefineLegalizerInfo(A, {631 getActionDefinitionsBuilder(G_CTPOP).legalFor({{s16, s16}});632 });633 // Build634 // Trunc it to s8.635 LLT s8{LLT::scalar(8)};636 LLT s16{LLT::scalar(16)};637 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);638 auto MIBCTPOP = B.buildInstr(TargetOpcode::G_CTPOP, {s8}, {MIBTrunc});639 AInfo Info(MF->getSubtarget());640 DummyGISelObserver Observer;641 LegalizerHelper Helper(*MF, Info, Observer, B);642 EXPECT_TRUE(Helper.widenScalar(*MIBCTPOP, 1, s16) ==643 LegalizerHelper::LegalizeResult::Legalized);644 645 auto CheckStr = R"(646 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC647 CHECK: [[Zext:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]648 CHECK: [[Ctpop:%[0-9]+]]:_(s16) = G_CTPOP [[Zext]]649 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Ctpop]]650 )";651 652 // Check653 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;654}655 656// CTTZ_ZERO_UNDEF widening.657TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ_ZERO_UNDEF) {658 setUp();659 if (!TM)660 GTEST_SKIP();661 662 // Declare your legalization info663 DefineLegalizerInfo(A, {664 getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF).legalFor({{s16, s16}});665 });666 // Build667 // Trunc it to s8.668 LLT s8{LLT::scalar(8)};669 LLT s16{LLT::scalar(16)};670 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);671 auto MIBCTTZ_ZERO_UNDEF =672 B.buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {s8}, {MIBTrunc});673 AInfo Info(MF->getSubtarget());674 DummyGISelObserver Observer;675 LegalizerHelper Helper(*MF, Info, Observer, B);676 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ_ZERO_UNDEF, 1, s16) ==677 LegalizerHelper::LegalizeResult::Legalized);678 679 auto CheckStr = R"(680 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC681 CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]682 CHECK: [[CttzZu:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[AnyExt]]683 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[CttzZu]]684 )";685 686 // Check687 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;688}689 690// CTTZ widening.691TEST_F(AArch64GISelMITest, WidenBitCountingCTTZ) {692 setUp();693 if (!TM)694 GTEST_SKIP();695 696 // Declare your legalization info697 DefineLegalizerInfo(A, {698 getActionDefinitionsBuilder(G_CTTZ).legalFor({{s16, s16}});699 });700 // Build701 // Trunc it to s8.702 LLT s8{LLT::scalar(8)};703 LLT s16{LLT::scalar(16)};704 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);705 auto MIBCTTZ = B.buildInstr(TargetOpcode::G_CTTZ, {s8}, {MIBTrunc});706 AInfo Info(MF->getSubtarget());707 DummyGISelObserver Observer;708 LegalizerHelper Helper(*MF, Info, Observer, B);709 EXPECT_TRUE(Helper.widenScalar(*MIBCTTZ, 1, s16) ==710 LegalizerHelper::LegalizeResult::Legalized);711 712 auto CheckStr = R"(713 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC714 CHECK: [[AnyExt:%[0-9]+]]:_(s16) = G_ANYEXT [[Trunc]]715 CHECK: [[Cst:%[0-9]+]]:_(s16) = G_CONSTANT i16 256716 CHECK: [[Or:%[0-9]+]]:_(s16) = G_OR [[AnyExt]]:_, [[Cst]]717 CHECK: [[Cttz:%[0-9]+]]:_(s16) = G_CTTZ_ZERO_UNDEF [[Or]]718 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC [[Cttz]]719 )";720 721 // Check722 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;723}724// UADDO widening.725TEST_F(AArch64GISelMITest, WidenUADDO) {726 setUp();727 if (!TM)728 GTEST_SKIP();729 730 // Declare your legalization info731 DefineLegalizerInfo(A, {732 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});733 });734 // Build735 // Trunc it to s8.736 LLT s8{LLT::scalar(8)};737 LLT s16{LLT::scalar(16)};738 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);739 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));740 auto MIBUAddO =741 B.buildInstr(TargetOpcode::G_UADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});742 AInfo Info(MF->getSubtarget());743 DummyGISelObserver Observer;744 LegalizerHelper Helper(*MF, Info, Observer, B);745 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==746 LegalizerHelper::LegalizeResult::Legalized);747 748 auto CheckStr = R"(749 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC750 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]751 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]752 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_753 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]754 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]755 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[ZEXT]]:_756 CHECK: G_TRUNC [[ADD]]757 )";758 759 // Check760 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;761}762 763// USUBO widening.764TEST_F(AArch64GISelMITest, WidenUSUBO) {765 setUp();766 if (!TM)767 GTEST_SKIP();768 769 // Declare your legalization info770 DefineLegalizerInfo(A, {771 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});772 });773 // Build774 // Trunc it to s8.775 LLT s8{LLT::scalar(8)};776 LLT s16{LLT::scalar(16)};777 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);778 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));779 auto MIBUSUBO =780 B.buildInstr(TargetOpcode::G_USUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});781 AInfo Info(MF->getSubtarget());782 DummyGISelObserver Observer;783 LegalizerHelper Helper(*MF, Info, Observer, B);784 EXPECT_TRUE(Helper.widenScalar(*MIBUSUBO, 0, s16) ==785 LegalizerHelper::LegalizeResult::Legalized);786 787 auto CheckStr = R"(788 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC789 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]790 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]791 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_792 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]793 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]794 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[ZEXT]]:_795 CHECK: G_TRUNC [[SUB]]796 )";797 798 // Check799 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;800}801 802// SADDO widening.803TEST_F(AArch64GISelMITest, WidenSADDO) {804 setUp();805 if (!TM)806 GTEST_SKIP();807 808 // Declare your legalization info809 DefineLegalizerInfo(A, {810 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});811 });812 // Build813 // Trunc it to s8.814 LLT s8{LLT::scalar(8)};815 LLT s16{LLT::scalar(16)};816 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);817 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));818 auto MIBSAddO =819 B.buildInstr(TargetOpcode::G_SADDO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});820 AInfo Info(MF->getSubtarget());821 DummyGISelObserver Observer;822 LegalizerHelper Helper(*MF, Info, Observer, B);823 EXPECT_TRUE(Helper.widenScalar(*MIBSAddO, 0, s16) ==824 LegalizerHelper::LegalizeResult::Legalized);825 826 auto CheckStr = R"(827 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC828 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]829 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]830 CHECK: [[ADD:%[0-9]+]]:_(s16) = G_ADD [[LHS]]:_, [[RHS]]:_831 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[ADD]]832 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]833 CHECK: G_ICMP intpred(ne), [[ADD]]:_(s16), [[SEXT]]:_834 CHECK: G_TRUNC [[ADD]]835 )";836 837 // Check838 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;839}840 841// SSUBO widening.842TEST_F(AArch64GISelMITest, WidenSSUBO) {843 setUp();844 if (!TM)845 GTEST_SKIP();846 847 // Declare your legalization info848 DefineLegalizerInfo(A, {849 getActionDefinitionsBuilder(G_SUB).legalFor({{s16, s16}});850 });851 // Build852 // Trunc it to s8.853 LLT s8{LLT::scalar(8)};854 LLT s16{LLT::scalar(16)};855 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);856 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));857 auto MIBSSUBO =858 B.buildInstr(TargetOpcode::G_SSUBO, {s8, CarryReg}, {MIBTrunc, MIBTrunc});859 AInfo Info(MF->getSubtarget());860 DummyGISelObserver Observer;861 LegalizerHelper Helper(*MF, Info, Observer, B);862 EXPECT_TRUE(Helper.widenScalar(*MIBSSUBO, 0, s16) ==863 LegalizerHelper::LegalizeResult::Legalized);864 865 auto CheckStr = R"(866 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC867 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]868 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]869 CHECK: [[SUB:%[0-9]+]]:_(s16) = G_SUB [[LHS]]:_, [[RHS]]:_870 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SUB]]871 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]872 CHECK: G_ICMP intpred(ne), [[SUB]]:_(s16), [[SEXT]]:_873 CHECK: G_TRUNC [[SUB]]874 )";875 876 // Check877 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;878}879 880TEST_F(AArch64GISelMITest, WidenUADDE) {881 setUp();882 if (!TM)883 GTEST_SKIP();884 885 // Declare your legalization info886 DefineLegalizerInfo(A, {887 getActionDefinitionsBuilder(G_UADDE).legalFor({{s16, s16}});888 });889 // Build890 // Trunc it to s8.891 LLT s8{LLT::scalar(8)};892 LLT s16{LLT::scalar(16)};893 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);894 auto CarryIn = B.buildUndef(LLT::scalar(1));895 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));896 auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDE, {s8, CarryReg},897 {MIBTrunc, MIBTrunc, CarryIn});898 AInfo Info(MF->getSubtarget());899 DummyGISelObserver Observer;900 LegalizerHelper Helper(*MF, Info, Observer, B);901 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==902 LegalizerHelper::LegalizeResult::Legalized);903 904 const char *CheckStr = R"(905 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC906 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF907 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]908 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]909 CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_910 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]]911 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]912 CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_913 CHECK: G_TRUNC [[UADDE]]914 )";915 916 // Check917 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;918}919 920TEST_F(AArch64GISelMITest, WidenUSUBE) {921 setUp();922 if (!TM)923 GTEST_SKIP();924 925 // Declare your legalization info926 DefineLegalizerInfo(A, {927 getActionDefinitionsBuilder(G_USUBE).legalFor({{s16, s16}});928 });929 // Build930 // Trunc it to s8.931 LLT s8{LLT::scalar(8)};932 LLT s16{LLT::scalar(16)};933 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);934 auto CarryIn = B.buildUndef(LLT::scalar(1));935 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));936 auto MIBUSUBE = B.buildInstr(TargetOpcode::G_USUBE, {s8, CarryReg},937 {MIBTrunc, MIBTrunc, CarryIn});938 AInfo Info(MF->getSubtarget());939 DummyGISelObserver Observer;940 LegalizerHelper Helper(*MF, Info, Observer, B);941 EXPECT_TRUE(Helper.widenScalar(*MIBUSUBE, 0, s16) ==942 LegalizerHelper::LegalizeResult::Legalized);943 944 const char *CheckStr = R"(945 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC946 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF947 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]948 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]949 CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_950 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]]951 CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]952 CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_953 CHECK: G_TRUNC [[USUBE]]954 )";955 956 // Check957 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;958}959 960TEST_F(AArch64GISelMITest, WidenSADDE) {961 setUp();962 if (!TM)963 GTEST_SKIP();964 965 // Declare your legalization info966 DefineLegalizerInfo(A, {967 getActionDefinitionsBuilder({G_SADDE, G_UADDE}).legalFor({{s16, s16}});968 });969 // Build970 // Trunc it to s8.971 LLT s8{LLT::scalar(8)};972 LLT s16{LLT::scalar(16)};973 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);974 auto CarryIn = B.buildUndef(LLT::scalar(1));975 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));976 auto MIBUAddO = B.buildInstr(TargetOpcode::G_SADDE, {s8, CarryReg},977 {MIBTrunc, MIBTrunc, CarryIn});978 AInfo Info(MF->getSubtarget());979 DummyGISelObserver Observer;980 LegalizerHelper Helper(*MF, Info, Observer, B);981 EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==982 LegalizerHelper::LegalizeResult::Legalized);983 984 const char *CheckStr = R"(985 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC986 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF987 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]988 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]989 CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_990 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]]991 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]992 CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_993 CHECK: G_TRUNC [[SADDE]]994 )";995 996 // Check997 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;998}999 1000TEST_F(AArch64GISelMITest, WidenSSUBE) {1001 setUp();1002 if (!TM)1003 GTEST_SKIP();1004 1005 // Declare your legalization info1006 DefineLegalizerInfo(A, {1007 getActionDefinitionsBuilder({G_SSUBE, G_USUBE}).legalFor({{s16, s16}});1008 });1009 // Build1010 // Trunc it to s8.1011 LLT s8{LLT::scalar(8)};1012 LLT s16{LLT::scalar(16)};1013 auto MIBTrunc = B.buildTrunc(s8, Copies[0]);1014 auto CarryIn = B.buildUndef(LLT::scalar(1));1015 Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));1016 auto MIBSSUBE = B.buildInstr(TargetOpcode::G_SSUBE, {s8, CarryReg},1017 {MIBTrunc, MIBTrunc, CarryIn});1018 AInfo Info(MF->getSubtarget());1019 DummyGISelObserver Observer;1020 LegalizerHelper Helper(*MF, Info, Observer, B);1021 EXPECT_TRUE(Helper.widenScalar(*MIBSSUBE, 0, s16) ==1022 LegalizerHelper::LegalizeResult::Legalized);1023 1024 const char *CheckStr = R"(1025 CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC1026 CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF1027 CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]1028 CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]1029 CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_1030 CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]]1031 CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]1032 CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_1033 CHECK: G_TRUNC [[SSUBE]]1034 )";1035 1036 // Check1037 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1038}1039 1040TEST_F(AArch64GISelMITest, WidenUMULOCondition) {1041 setUp();1042 if (!TM)1043 GTEST_SKIP();1044 1045 // Declare your legalization info1046 DefineLegalizerInfo(A, {1047 getActionDefinitionsBuilder(G_ADD).legalFor({{s16, s16}});1048 });1049 1050 LLT s32 = LLT::scalar(32);1051 LLT s64 = LLT::scalar(64);1052 1053 auto UMulo =1054 B.buildInstr(TargetOpcode::G_UMULO, {s64, LLT::scalar(1)},1055 {Copies[0], Copies[1]});1056 AInfo Info(MF->getSubtarget());1057 DummyGISelObserver Observer;1058 LegalizerHelper Helper(*MF, Info, Observer, B);1059 1060 B.setInstrAndDebugLoc(*UMulo);1061 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1062 Helper.widenScalar(*UMulo, 1, s32));1063 1064 auto CheckStr = R"(1065 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY1066 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY1067 CHECK: [[ADD:%[0-9]+]]:_(s64), [[OVERFLOW:%[0-9]+]]:_(s32) = G_UMULO [[COPY0]]:_, [[COPY1]]:_1068 CHECK: {{[0-9]+}}:_(s1) = G_TRUNC [[OVERFLOW]]1069 )";1070 1071 // Check1072 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1073}1074 1075TEST_F(AArch64GISelMITest, NarrowUADDO) {1076 setUp();1077 if (!TM)1078 GTEST_SKIP();1079 1080 LLT S1 = LLT::scalar(1);1081 LLT S32 = LLT::scalar(32);1082 LLT S96 = LLT::scalar(96);1083 DefineLegalizerInfo(A, {1084 getActionDefinitionsBuilder({G_UADDO, G_UADDE})1085 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1086 });1087 1088 auto Op0 = B.buildUndef(S96);1089 auto Op1 = B.buildUndef(S96);1090 auto UADDO = B.buildUAddo(S96, S1, Op0, Op1);1091 1092 AInfo Info(MF->getSubtarget());1093 DummyGISelObserver Observer;1094 LegalizerHelper Helper(*MF, Info, Observer, B);1095 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1096 Helper.narrowScalar(*UADDO, 0, S32));1097 1098 const char *CheckStr = R"(1099 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1100 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1101 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1102 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1103 CHECK: [[UADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_1104 CHECK: [[UADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1105 CHECK: [[UADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1106 CHECK: [[UADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDO0]]:_(s32), [[UADDO1]]:_(s32), [[UADDO2]]:_(s32)1107 )";1108 1109 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1110}1111 1112TEST_F(AArch64GISelMITest, NarrowUSUBO) {1113 setUp();1114 if (!TM)1115 GTEST_SKIP();1116 1117 LLT S1 = LLT::scalar(1);1118 LLT S32 = LLT::scalar(32);1119 LLT S96 = LLT::scalar(96);1120 DefineLegalizerInfo(A, {1121 getActionDefinitionsBuilder({G_USUBO, G_USUBE})1122 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1123 });1124 1125 auto Op0 = B.buildUndef(S96);1126 auto Op1 = B.buildUndef(S96);1127 auto USUBO = B.buildUSubo(S96, S1, Op0, Op1);1128 1129 AInfo Info(MF->getSubtarget());1130 DummyGISelObserver Observer;1131 LegalizerHelper Helper(*MF, Info, Observer, B);1132 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1133 Helper.narrowScalar(*USUBO, 0, S32));1134 1135 const char *CheckStr = R"(1136 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1137 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1138 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1139 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1140 CHECK: [[USUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_1141 CHECK: [[USUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1142 CHECK: [[USUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1143 CHECK: [[USUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBO0]]:_(s32), [[USUBO1]]:_(s32), [[USUBO2]]:_(s32)1144 )";1145 1146 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1147}1148 1149TEST_F(AArch64GISelMITest, NarrowSADDO) {1150 setUp();1151 if (!TM)1152 GTEST_SKIP();1153 1154 LLT S1 = LLT::scalar(1);1155 LLT S32 = LLT::scalar(32);1156 LLT S96 = LLT::scalar(96);1157 DefineLegalizerInfo(A, {1158 getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_SADDE})1159 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1160 });1161 1162 auto Op0 = B.buildUndef(S96);1163 auto Op1 = B.buildUndef(S96);1164 auto SADDO = B.buildSAddo(S96, S1, Op0, Op1);1165 1166 AInfo Info(MF->getSubtarget());1167 DummyGISelObserver Observer;1168 LegalizerHelper Helper(*MF, Info, Observer, B);1169 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1170 Helper.narrowScalar(*SADDO, 0, S32));1171 1172 const char *CheckStr = R"(1173 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1174 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1175 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1176 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1177 CHECK: [[SADDO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDO [[OP0_0]]:_, [[OP1_0]]:_1178 CHECK: [[SADDO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1179 CHECK: [[SADDO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1180 CHECK: [[SADDO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDO0]]:_(s32), [[SADDO1]]:_(s32), [[SADDO2]]:_(s32)1181 )";1182 1183 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1184}1185 1186TEST_F(AArch64GISelMITest, NarrowSSUBO) {1187 setUp();1188 if (!TM)1189 GTEST_SKIP();1190 1191 LLT S1 = LLT::scalar(1);1192 LLT S32 = LLT::scalar(32);1193 LLT S96 = LLT::scalar(96);1194 DefineLegalizerInfo(A, {1195 getActionDefinitionsBuilder({G_USUBO, G_USUBE, G_SSUBE})1196 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1197 });1198 1199 auto Op0 = B.buildUndef(S96);1200 auto Op1 = B.buildUndef(S96);1201 auto SSUBO = B.buildSSubo(S96, S1, Op0, Op1);1202 1203 AInfo Info(MF->getSubtarget());1204 DummyGISelObserver Observer;1205 LegalizerHelper Helper(*MF, Info, Observer, B);1206 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1207 Helper.narrowScalar(*SSUBO, 0, S32));1208 1209 const char *CheckStr = R"(1210 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1211 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1212 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1213 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1214 CHECK: [[SSUBO0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBO [[OP0_0]]:_, [[OP1_0]]:_1215 CHECK: [[SSUBO1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1216 CHECK: [[SSUBO2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1217 CHECK: [[SSUBO:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBO0]]:_(s32), [[SSUBO1]]:_(s32), [[SSUBO2]]:_(s32)1218 )";1219 1220 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1221}1222 1223TEST_F(AArch64GISelMITest, NarrowUADDE) {1224 setUp();1225 if (!TM)1226 GTEST_SKIP();1227 1228 LLT S1 = LLT::scalar(1);1229 LLT S32 = LLT::scalar(32);1230 LLT S96 = LLT::scalar(96);1231 DefineLegalizerInfo(A, {1232 getActionDefinitionsBuilder(G_UADDE).legalFor(1233 {{LLT::scalar(32), LLT::scalar(1)}});1234 });1235 1236 auto Op0 = B.buildUndef(S96);1237 auto Op1 = B.buildUndef(S96);1238 auto Op2 = B.buildUndef(S1);1239 auto UADDE = B.buildUAdde(S96, S1, Op0, Op1, Op2);1240 1241 AInfo Info(MF->getSubtarget());1242 DummyGISelObserver Observer;1243 LegalizerHelper Helper(*MF, Info, Observer, B);1244 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1245 Helper.narrowScalar(*UADDE, 0, S32));1246 1247 const char *CheckStr = R"(1248 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1249 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1250 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF1251 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1252 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1253 CHECK: [[UADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_1254 CHECK: [[UADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1255 CHECK: [[UADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_UADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1256 CHECK: [[UADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[UADDE0]]:_(s32), [[UADDE1]]:_(s32), [[UADDE2]]:_(s32)1257 )";1258 1259 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1260}1261 1262TEST_F(AArch64GISelMITest, NarrowUSUBE) {1263 setUp();1264 if (!TM)1265 GTEST_SKIP();1266 1267 LLT S1 = LLT::scalar(1);1268 LLT S32 = LLT::scalar(32);1269 LLT S96 = LLT::scalar(96);1270 DefineLegalizerInfo(A, {1271 getActionDefinitionsBuilder(G_USUBE).legalFor(1272 {{LLT::scalar(32), LLT::scalar(1)}});1273 });1274 1275 auto Op0 = B.buildUndef(S96);1276 auto Op1 = B.buildUndef(S96);1277 auto Op2 = B.buildUndef(S1);1278 auto USUBE = B.buildUSube(S96, S1, Op0, Op1, Op2);1279 1280 AInfo Info(MF->getSubtarget());1281 DummyGISelObserver Observer;1282 LegalizerHelper Helper(*MF, Info, Observer, B);1283 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1284 Helper.narrowScalar(*USUBE, 0, S32));1285 1286 const char *CheckStr = R"(1287 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1288 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1289 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF1290 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1291 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1292 CHECK: [[USUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_1293 CHECK: [[USUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1294 CHECK: [[USUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_USUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1295 CHECK: [[USUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[USUBE0]]:_(s32), [[USUBE1]]:_(s32), [[USUBE2]]:_(s32)1296 )";1297 1298 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1299}1300 1301TEST_F(AArch64GISelMITest, NarrowSADDE) {1302 setUp();1303 if (!TM)1304 GTEST_SKIP();1305 1306 LLT S1 = LLT::scalar(1);1307 LLT S32 = LLT::scalar(32);1308 LLT S96 = LLT::scalar(96);1309 DefineLegalizerInfo(A, {1310 getActionDefinitionsBuilder({G_SADDE, G_UADDE})1311 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1312 });1313 1314 auto Op0 = B.buildUndef(S96);1315 auto Op1 = B.buildUndef(S96);1316 auto Op2 = B.buildUndef(S1);1317 auto SADDE = B.buildSAdde(S96, S1, Op0, Op1, Op2);1318 1319 AInfo Info(MF->getSubtarget());1320 DummyGISelObserver Observer;1321 LegalizerHelper Helper(*MF, Info, Observer, B);1322 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1323 Helper.narrowScalar(*SADDE, 0, S32));1324 1325 const char *CheckStr = R"(1326 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1327 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1328 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF1329 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1330 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1331 CHECK: [[SADDE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_UADDE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_1332 CHECK: [[SADDE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_UADDE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1333 CHECK: [[SADDE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SADDE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1334 CHECK: [[SADDE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SADDE0]]:_(s32), [[SADDE1]]:_(s32), [[SADDE2]]:_(s32)1335 )";1336 1337 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1338}1339 1340TEST_F(AArch64GISelMITest, NarrowSSUBE) {1341 setUp();1342 if (!TM)1343 GTEST_SKIP();1344 1345 LLT S1 = LLT::scalar(1);1346 LLT S32 = LLT::scalar(32);1347 LLT S96 = LLT::scalar(96);1348 DefineLegalizerInfo(A, {1349 getActionDefinitionsBuilder({G_SSUBE, G_USUBE})1350 .legalFor({{LLT::scalar(32), LLT::scalar(1)}});1351 });1352 1353 auto Op0 = B.buildUndef(S96);1354 auto Op1 = B.buildUndef(S96);1355 auto Op2 = B.buildUndef(S1);1356 auto SSUBE = B.buildSSube(S96, S1, Op0, Op1, Op2);1357 1358 AInfo Info(MF->getSubtarget());1359 DummyGISelObserver Observer;1360 LegalizerHelper Helper(*MF, Info, Observer, B);1361 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1362 Helper.narrowScalar(*SSUBE, 0, S32));1363 1364 const char *CheckStr = R"(1365 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1366 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s96) = G_IMPLICIT_DEF1367 CHECK: [[IMP_DEF2:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF1368 CHECK: [[OP0_0:%[0-9]+]]:_(s32), [[OP0_1:%[0-9]+]]:_(s32), [[OP0_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]1369 CHECK: [[OP1_0:%[0-9]+]]:_(s32), [[OP1_1:%[0-9]+]]:_(s32), [[OP1_2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]1370 CHECK: [[SSUBE0:%[0-9]+]]:_(s32), [[CARRY0:%[0-9]+]]:_(s1) = G_USUBE [[OP0_0]]:_, [[OP1_0]]:_, [[IMP_DEF2]]:_1371 CHECK: [[SSUBE1:%[0-9]+]]:_(s32), [[CARRY1:%[0-9]+]]:_(s1) = G_USUBE [[OP0_1]]:_, [[OP1_1]]:_, [[CARRY0]]:_1372 CHECK: [[SSUBE2:%[0-9]+]]:_(s32), [[CARRY2:%[0-9]+]]:_(s1) = G_SSUBE [[OP0_2]]:_, [[OP1_2]]:_, [[CARRY1]]:_1373 CHECK: [[SSUBE:%[0-9]+]]:_(s96) = G_MERGE_VALUES [[SSUBE0]]:_(s32), [[SSUBE1]]:_(s32), [[SSUBE2]]:_(s32)1374 )";1375 1376 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1377}1378 1379TEST_F(AArch64GISelMITest, FewerElementsAnd) {1380 setUp();1381 if (!TM)1382 GTEST_SKIP();1383 1384 const LLT V2S32 = LLT::fixed_vector(2, 32);1385 const LLT V5S32 = LLT::fixed_vector(5, 32);1386 1387 // Declare your legalization info1388 DefineLegalizerInfo(A, {1389 getActionDefinitionsBuilder(G_AND)1390 .legalFor({s32});1391 });1392 1393 auto Op0 = B.buildUndef(V5S32);1394 auto Op1 = B.buildUndef(V5S32);1395 auto And = B.buildAnd(V5S32, Op0, Op1);1396 1397 AInfo Info(MF->getSubtarget());1398 DummyGISelObserver Observer;1399 LegalizerHelper Helper(*MF, Info, Observer, B);1400 B.setInstr(*And);1401 EXPECT_TRUE(Helper.fewerElementsVector(*And, 0, V2S32) ==1402 LegalizerHelper::LegalizeResult::Legalized);1403 1404 auto CheckStr = R"(1405 CHECK: [[IMP_DEF0:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF1406 CHECK: [[IMP_DEF1:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF1407 CHECK: [[VALUE0:%[0-9]+]]:_(s32), [[VALUE1:%[0-9]+]]:_(s32), [[VALUE2:%[0-9]+]]:_(s32), [[VALUE3:%[0-9]+]]:_(s32), [[VALUE4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF0]]:_(<5 x s32>)1408 CHECK: [[VECTOR0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE0]]:_(s32), [[VALUE1]]:_(s32)1409 CHECK: [[VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE2]]:_(s32), [[VALUE3]]:_(s32)1410 CHECK: [[VALUE5:%[0-9]+]]:_(s32), [[VALUE6:%[0-9]+]]:_(s32), [[VALUE7:%[0-9]+]]:_(s32), [[VALUE8:%[0-9]+]]:_(s32), [[VALUE9:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[IMP_DEF1]]:_(<5 x s32>)1411 CHECK: [[VECTOR2:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE5]]:_(s32), [[VALUE6]]:_(s32)1412 CHECK: [[VECTOR3:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[VALUE7]]:_(s32), [[VALUE8]]:_(s32)1413 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR0]]:_, [[VECTOR2]]:_1414 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[VECTOR1]]:_, [[VECTOR3]]:_1415 CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[VALUE4]]:_, [[VALUE9]]:_1416 CHECK: [[AND0_E0:%[0-9]+]]:_(s32), [[AND0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND0]]:_(<2 x s32>)1417 CHECK: [[AND1_E0:%[0-9]+]]:_(s32), [[AND1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND1]]:_(<2 x s32>)1418 CHECK: [[RESULT:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[AND0_E0]]:_(s32), [[AND0_E1]]:_(s32), [[AND1_E0]]:_(s32), [[AND1_E1]]:_(s32), [[AND2]]:_(s32)1419 )";1420 1421 // Check1422 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1423}1424 1425TEST_F(AArch64GISelMITest, MoreElementsAnd) {1426 setUp();1427 if (!TM)1428 GTEST_SKIP();1429 1430 LLT s32 = LLT::scalar(32);1431 LLT v2s32 = LLT::fixed_vector(2, 32);1432 LLT v6s32 = LLT::fixed_vector(6, 32);1433 1434 LegalizerInfo LI;1435 LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)1436 .legalFor({v6s32})1437 .clampMinNumElements(0, s32, 6);1438 LI.getLegacyLegalizerInfo().computeTables();1439 1440 DummyGISelObserver Observer;1441 LegalizerHelper Helper(*MF, LI, Observer, B);1442 1443 B.setInsertPt(*EntryMBB, EntryMBB->end());1444 1445 auto Val0 = B.buildBitcast(v2s32, Copies[0]);1446 auto Val1 = B.buildBitcast(v2s32, Copies[1]);1447 1448 auto And = B.buildAnd(v2s32, Val0, Val1);1449 1450 B.setInstr(*And);1451 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1452 Helper.moreElementsVector(*And, 0, v6s32));1453 1454 auto CheckStr = R"(1455 CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST1456 CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST1457 1458 CHECK: [[BITCAST0_E0:%[0-9]+]]:_(s32), [[BITCAST0_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST0]]:_(<2 x s32>)1459 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF1460 CHECK: [[BITCAST0_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST0_E0]]:_(s32), [[BITCAST0_E1]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32), [[IMP_DEF0]]:_(s32)1461 1462 CHECK: [[BITCAST1_E0:%[0-9]+]]:_(s32), [[BITCAST1_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST1]]:_(<2 x s32>)1463 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF1464 CHECK: [[BITCAST1_LARGE:%[0-9]+]]:_(<6 x s32>) = G_BUILD_VECTOR [[BITCAST1_E0]]:_(s32), [[BITCAST1_E1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32), [[IMP_DEF1]]:_(s32)1465 1466 CHECK: [[AND:%[0-9]+]]:_(<6 x s32>) = G_AND [[BITCAST0_LARGE]]:_, [[BITCAST1_LARGE]]:_1467 1468 CHECK: [[AND_E0:%[0-9]+]]:_(s32), [[AND_E1:%[0-9]+]]:_(s32), [[AND_E2:%[0-9]+]]:_(s32), [[AND_E3:%[0-9]+]]:_(s32), [[AND_E4:%[0-9]+]]:_(s32), [[AND_E5:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[AND]]:_(<6 x s32>)1469 CHECK: (<2 x s32>) = G_BUILD_VECTOR [[AND_E0]]:_(s32), [[AND_E1]]:_(s32)1470 )";1471 1472 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1473}1474 1475TEST_F(AArch64GISelMITest, FewerElementsPhi) {1476 setUp();1477 if (!TM)1478 GTEST_SKIP();1479 1480 LLT s1 = LLT::scalar(1);1481 LLT s32 = LLT::scalar(32);1482 LLT s64 = LLT::scalar(64);1483 LLT v2s32 = LLT::fixed_vector(2, 32);1484 LLT v5s32 = LLT::fixed_vector(5, 32);1485 1486 LegalizerInfo LI;1487 LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)1488 .legalFor({v2s32})1489 .clampMinNumElements(0, s32, 2);1490 LI.getLegacyLegalizerInfo().computeTables();1491 1492 LLT PhiTy = v5s32;1493 DummyGISelObserver Observer;1494 LegalizerHelper Helper(*MF, LI, Observer, B);1495 B.setMBB(*EntryMBB);1496 1497 MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();1498 MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();1499 MF->insert(MF->end(), MidMBB);1500 MF->insert(MF->end(), EndMBB);1501 1502 EntryMBB->addSuccessor(MidMBB);1503 EntryMBB->addSuccessor(EndMBB);1504 MidMBB->addSuccessor(EndMBB);1505 1506 auto InitVal = B.buildUndef(PhiTy);1507 auto InitOtherVal = B.buildConstant(s64, 999);1508 1509 auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);1510 B.buildBrCond(ICmp.getReg(0), *MidMBB);1511 B.buildBr(*EndMBB);1512 1513 1514 B.setMBB(*MidMBB);1515 auto MidVal = B.buildUndef(PhiTy);1516 auto MidOtherVal = B.buildConstant(s64, 345);1517 B.buildBr(*EndMBB);1518 1519 B.setMBB(*EndMBB);1520 auto Phi = B.buildInstr(TargetOpcode::G_PHI)1521 .addDef(MRI->createGenericVirtualRegister(PhiTy))1522 .addUse(InitVal.getReg(0))1523 .addMBB(EntryMBB)1524 .addUse(MidVal.getReg(0))1525 .addMBB(MidMBB);1526 1527 // Insert another irrelevant phi to make sure the rebuild is inserted after1528 // it.1529 B.buildInstr(TargetOpcode::G_PHI)1530 .addDef(MRI->createGenericVirtualRegister(s64))1531 .addUse(InitOtherVal.getReg(0))1532 .addMBB(EntryMBB)1533 .addUse(MidOtherVal.getReg(0))1534 .addMBB(MidMBB);1535 1536 // Add some use instruction after the phis.1537 B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));1538 1539 B.setInstr(*Phi);1540 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1541 Helper.fewerElementsVector(*Phi, 0, v2s32));1542 1543 auto CheckStr = R"(1544 CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF1545 CHECK: [[INITVAL_E0:%[0-9]+]]:_(s32), [[INITVAL_E1:%[0-9]+]]:_(s32), [[INITVAL_E2:%[0-9]+]]:_(s32), [[INITVAL_E3:%[0-9]+]]:_(s32), [[INITVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[INITVAL]]:_(<5 x s32>)1546 CHECK: [[INITVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E0]]:_(s32), [[INITVAL_E1]]:_(s32)1547 CHECK: [[INITVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[INITVAL_E2]]:_(s32), [[INITVAL_E3]]:_(s32)1548 CHECK: G_BRCOND1549 1550 CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF1551 CHECK: [[MIDVAL_E0:%[0-9]+]]:_(s32), [[MIDVAL_E1:%[0-9]+]]:_(s32), [[MIDVAL_E2:%[0-9]+]]:_(s32), [[MIDVAL_E3:%[0-9]+]]:_(s32), [[MIDVAL_E4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[MIDVAL]]:_(<5 x s32>)1552 CHECK: [[MIDVAL_E01:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E0]]:_(s32), [[MIDVAL_E1]]:_(s32)1553 CHECK: [[MIDVAL_E23:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[MIDVAL_E2]]:_(s32), [[MIDVAL_E3]]:_(s32)1554 CHECK: G_BR1555 1556 CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E01]]:_(<2 x s32>), %bb.0, [[MIDVAL_E01]]:_(<2 x s32>), %bb.11557 CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[INITVAL_E23]]:_(<2 x s32>), %bb.0, [[MIDVAL_E23]]:_(<2 x s32>), %bb.11558 CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[INITVAL_E4]]:_(s32), %bb.0, [[MIDVAL_E4]]:_(s32), %bb.11559 1560 CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI1561 1562 CHECK: [[UNMERGE0:%[0-9]+]]:_(s32), [[UNMERGE1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI0]]:_(<2 x s32>)1563 CHECK: [[UNMERGE2:%[0-9]+]]:_(s32), [[UNMERGE3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI1]]:_(<2 x s32>)1564 CHECK: [[BV:%[0-9]+]]:_(<5 x s32>) = G_BUILD_VECTOR [[UNMERGE0]]:_(s32), [[UNMERGE1]]:_(s32), [[UNMERGE2]]:_(s32), [[UNMERGE3]]:_(s32), [[PHI2]]:_(s32)1565 CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[BV]]:_, [[BV]]:_1566 )";1567 1568 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1569}1570 1571// FNEG expansion in terms of XOR1572TEST_F(AArch64GISelMITest, LowerFNEG) {1573 setUp();1574 if (!TM)1575 GTEST_SKIP();1576 1577 // Declare your legalization info1578 DefineLegalizerInfo(A, {1579 getActionDefinitionsBuilder(G_FSUB).legalFor({s64});1580 });1581 1582 // Build Instr. Make sure FMF are preserved.1583 auto FAdd =1584 B.buildInstr(TargetOpcode::G_FADD, {LLT::scalar(64)}, {Copies[0], Copies[1]},1585 MachineInstr::MIFlag::FmNsz);1586 1587 // Should not propagate the flags of src instruction.1588 auto FNeg0 =1589 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {FAdd.getReg(0)},1590 {MachineInstr::MIFlag::FmArcp});1591 1592 // Preserve the one flag.1593 auto FNeg1 =1594 B.buildInstr(TargetOpcode::G_FNEG, {LLT::scalar(64)}, {Copies[0]},1595 MachineInstr::MIFlag::FmNoInfs);1596 1597 AInfo Info(MF->getSubtarget());1598 DummyGISelObserver Observer;1599 LegalizerHelper Helper(*MF, Info, Observer, B);1600 // Perform Legalization1601 B.setInstr(*FNeg0);1602 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1603 Helper.lower(*FNeg0, 0, LLT::scalar(64)));1604 B.setInstr(*FNeg1);1605 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1606 Helper.lower(*FNeg1, 0, LLT::scalar(64)));1607 1608 auto CheckStr = R"(1609 CHECK: [[FADD:%[0-9]+]]:_(s64) = nsz G_FADD %0:_, %1:_1610 CHECK: [[CONST0:%[0-9]+]]:_(s64) = G_CONSTANT i64 -92233720368547758081611 CHECK: [[FSUB0:%[0-9]+]]:_(s64) = G_XOR [[FADD]]:_, [[CONST0]]:_1612 CHECK: [[CONST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -92233720368547758081613 CHECK: [[FSUB1:%[0-9]+]]:_(s64) = G_XOR %0:_, [[CONST1]]:_1614 )";1615 1616 // Check1617 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1618}1619 1620TEST_F(AArch64GISelMITest, LowerMinMax) {1621 setUp();1622 if (!TM)1623 GTEST_SKIP();1624 1625 LLT s64 = LLT::scalar(64);1626 LLT v2s32 = LLT::fixed_vector(2, 32);1627 1628 DefineLegalizerInfo(A, {1629 getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})1630 .lowerFor({s64, LLT::fixed_vector(2, s32)});1631 });1632 1633 auto SMin = B.buildSMin(s64, Copies[0], Copies[1]);1634 auto SMax = B.buildSMax(s64, Copies[0], Copies[1]);1635 auto UMin = B.buildUMin(s64, Copies[0], Copies[1]);1636 auto UMax = B.buildUMax(s64, Copies[0], Copies[1]);1637 1638 auto VecVal0 = B.buildBitcast(v2s32, Copies[0]);1639 auto VecVal1 = B.buildBitcast(v2s32, Copies[1]);1640 1641 auto SMinV = B.buildSMin(v2s32, VecVal0, VecVal1);1642 auto SMaxV = B.buildSMax(v2s32, VecVal0, VecVal1);1643 auto UMinV = B.buildUMin(v2s32, VecVal0, VecVal1);1644 auto UMaxV = B.buildUMax(v2s32, VecVal0, VecVal1);1645 1646 AInfo Info(MF->getSubtarget());1647 DummyGISelObserver Observer;1648 LegalizerHelper Helper(*MF, Info, Observer, B);1649 B.setInstr(*SMin);1650 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1651 Helper.lower(*SMin, 0, s64));1652 B.setInstr(*SMax);1653 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1654 Helper.lower(*SMax, 0, s64));1655 B.setInstr(*UMin);1656 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1657 Helper.lower(*UMin, 0, s64));1658 B.setInstr(*UMax);1659 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1660 Helper.lower(*UMax, 0, s64));1661 1662 B.setInstr(*SMinV);1663 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1664 Helper.lower(*SMinV, 0, v2s32));1665 B.setInstr(*SMaxV);1666 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1667 Helper.lower(*SMaxV, 0, v2s32));1668 B.setInstr(*UMinV);1669 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1670 Helper.lower(*UMinV, 0, v2s32));1671 B.setInstr(*UMaxV);1672 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1673 Helper.lower(*UMaxV, 0, v2s32));1674 1675 auto CheckStr = R"(1676 CHECK: [[CMP0:%[0-9]+]]:_(s1) = G_ICMP intpred(slt), %0:_(s64), %1:_1677 CHECK: [[SMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP0]]:_(s1), %0:_, %1:_1678 1679 CHECK: [[CMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(sgt), %0:_(s64), %1:_1680 CHECK: [[SMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP1]]:_(s1), %0:_, %1:_1681 1682 CHECK: [[CMP2:%[0-9]+]]:_(s1) = G_ICMP intpred(ult), %0:_(s64), %1:_1683 CHECK: [[UMIN:%[0-9]+]]:_(s64) = G_SELECT [[CMP2]]:_(s1), %0:_, %1:_1684 1685 CHECK: [[CMP3:%[0-9]+]]:_(s1) = G_ICMP intpred(ugt), %0:_(s64), %1:_1686 CHECK: [[UMAX:%[0-9]+]]:_(s64) = G_SELECT [[CMP3]]:_(s1), %0:_, %1:_1687 1688 CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %0:_(s64)1689 CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST %1:_(s64)1690 1691 CHECK: [[VCMP0:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(slt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_1692 CHECK: [[SMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP0]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_1693 1694 CHECK: [[VCMP1:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(sgt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_1695 CHECK: [[SMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP1]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_1696 1697 CHECK: [[VCMP2:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ult), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_1698 CHECK: [[UMINV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP2]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_1699 1700 CHECK: [[VCMP3:%[0-9]+]]:_(<2 x s1>) = G_ICMP intpred(ugt), [[VEC0]]:_(<2 x s32>), [[VEC1]]:_1701 CHECK: [[UMAXV:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[VCMP3]]:_(<2 x s1>), [[VEC0]]:_, [[VEC1]]:_1702 )";1703 1704 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1705}1706 1707TEST_F(AArch64GISelMITest, WidenScalarBuildVector) {1708 setUp();1709 if (!TM)1710 GTEST_SKIP();1711 1712 LLT S32 = LLT::scalar(32);1713 LLT S16 = LLT::scalar(16);1714 LLT V2S16 = LLT::fixed_vector(2, S16);1715 LLT V2S32 = LLT::fixed_vector(2, S32);1716 1717 DefineLegalizerInfo(A, {1718 getActionDefinitionsBuilder({G_SMIN, G_SMAX, G_UMIN, G_UMAX})1719 .lowerFor({s64, LLT::fixed_vector(2, s32)});1720 });1721 1722 AInfo Info(MF->getSubtarget());1723 DummyGISelObserver Observer;1724 LegalizerHelper Helper(*MF, Info, Observer, B);1725 B.setInsertPt(*EntryMBB, EntryMBB->end());1726 1727 Register Constant0 = B.buildConstant(S16, 1).getReg(0);1728 Register Constant1 = B.buildConstant(S16, 2).getReg(0);1729 auto BV0 = B.buildBuildVector(V2S16, {Constant0, Constant1});1730 auto BV1 = B.buildBuildVector(V2S16, {Constant0, Constant1});1731 1732 B.setInstr(*BV0);1733 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1734 Helper.widenScalar(*BV0, 0, V2S32));1735 B.setInstr(*BV1);1736 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1737 Helper.widenScalar(*BV1, 1, S32));1738 1739 auto CheckStr = R"(1740 CHECK: [[K0:%[0-9]+]]:_(s16) = G_CONSTANT i16 11741 CHECK-NEXT: [[K1:%[0-9]+]]:_(s16) = G_CONSTANT i16 21742 CHECK-NEXT: [[EXT_K0_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]1743 CHECK-NEXT: [[EXT_K1_0:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]1744 CHECK-NEXT: [[BV0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[EXT_K0_0]]:_(s32), [[EXT_K1_0]]:_(s32)1745 CHECK-NEXT: [[BV0_TRUNC:%[0-9]+]]:_(<2 x s16>) = G_TRUNC [[BV0]]1746 1747 CHECK: [[EXT_K0_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K0]]1748 CHECK-NEXT: [[EXT_K1_1:%[0-9]+]]:_(s32) = G_ANYEXT [[K1]]1749 1750 CHECK-NEXT: [[BV1:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR_TRUNC [[EXT_K0_1]]:_(s32), [[EXT_K1_1]]:_(s32)1751 )";1752 1753 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1754}1755 1756TEST_F(AArch64GISelMITest, LowerMergeValues) {1757 setUp();1758 if (!TM)1759 GTEST_SKIP();1760 1761 const LLT S32 = LLT::scalar(32);1762 const LLT S24 = LLT::scalar(24);1763 const LLT S21 = LLT::scalar(21);1764 const LLT S16 = LLT::scalar(16);1765 const LLT S9 = LLT::scalar(9);1766 const LLT S8 = LLT::scalar(8);1767 const LLT S3 = LLT::scalar(3);1768 1769 DefineLegalizerInfo(A, {1770 getActionDefinitionsBuilder(G_UNMERGE_VALUES)1771 .widenScalarIf(typeIs(1, LLT::scalar(3)), changeTo(1, LLT::scalar(9)));1772 });1773 1774 AInfo Info(MF->getSubtarget());1775 DummyGISelObserver Observer;1776 LegalizerHelper Helper(*MF, Info, Observer, B);1777 B.setInsertPt(*EntryMBB, EntryMBB->end());1778 1779 // 24 = 3 3 3 3 3 3 3 31780 // => 91781 //1782 // This can do 3 merges, but need an extra implicit_def.1783 SmallVector<Register, 8> Merge0Ops;1784 for (int I = 0; I != 8; ++I)1785 Merge0Ops.push_back(B.buildConstant(S3, I).getReg(0));1786 1787 auto Merge0 = B.buildMergeLikeInstr(S24, Merge0Ops);1788 1789 // 21 = 3 3 3 3 3 3 31790 // => 9, 2 extra implicit_def needed1791 //1792 SmallVector<Register, 8> Merge1Ops;1793 for (int I = 0; I != 7; ++I)1794 Merge1Ops.push_back(B.buildConstant(S3, I).getReg(0));1795 1796 auto Merge1 = B.buildMergeLikeInstr(S21, Merge1Ops);1797 1798 SmallVector<Register, 8> Merge2Ops;1799 for (int I = 0; I != 2; ++I)1800 Merge2Ops.push_back(B.buildConstant(S8, I).getReg(0));1801 1802 auto Merge2 = B.buildMergeLikeInstr(S16, Merge2Ops);1803 1804 B.setInstr(*Merge0);1805 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1806 Helper.widenScalar(*Merge0, 1, S9));1807 B.setInstr(*Merge1);1808 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1809 Helper.widenScalar(*Merge1, 1, S9));1810 1811 // Request a source size greater than the original destination size.1812 B.setInstr(*Merge2);1813 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1814 Helper.widenScalar(*Merge2, 1, S32));1815 1816 auto CheckStr = R"(1817 CHECK: [[K0:%[0-9]+]]:_(s3) = G_CONSTANT i3 01818 CHECK-NEXT: [[K1:%[0-9]+]]:_(s3) = G_CONSTANT i3 11819 CHECK-NEXT: [[K2:%[0-9]+]]:_(s3) = G_CONSTANT i3 21820 CHECK-NEXT: [[K3:%[0-9]+]]:_(s3) = G_CONSTANT i3 31821 CHECK-NEXT: [[K4:%[0-9]+]]:_(s3) = G_CONSTANT i3 -41822 CHECK-NEXT: [[K5:%[0-9]+]]:_(s3) = G_CONSTANT i3 -31823 CHECK-NEXT: [[K6:%[0-9]+]]:_(s3) = G_CONSTANT i3 -21824 CHECK-NEXT: [[K7:%[0-9]+]]:_(s3) = G_CONSTANT i3 -11825 CHECK-NEXT: [[IMPDEF0:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF1826 CHECK-NEXT: [[MERGE0:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K0]]:_(s3), [[K1]]:_(s3), [[K2]]:_(s3)1827 CHECK-NEXT: [[MERGE1:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K3]]:_(s3), [[K4]]:_(s3), [[K5]]:_(s3)1828 CHECK-NEXT: [[MERGE2:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K6]]:_(s3), [[K7]]:_(s3), [[IMPDEF0]]:_(s3)1829 CHECK-NEXT: [[MERGE3:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE0]]:_(s9), [[MERGE1]]:_(s9), [[MERGE2]]:_(s9)1830 CHECK-NEXT: (s24) = G_TRUNC [[MERGE3]]:_(s27)1831 1832 1833 CHECK: [[K8:%[0-9]+]]:_(s3) = G_CONSTANT i3 01834 CHECK-NEXT: [[K9:%[0-9]+]]:_(s3) = G_CONSTANT i3 11835 CHECK-NEXT: [[K10:%[0-9]+]]:_(s3) = G_CONSTANT i3 21836 CHECK-NEXT: [[K11:%[0-9]+]]:_(s3) = G_CONSTANT i3 31837 CHECK-NEXT: [[K12:%[0-9]+]]:_(s3) = G_CONSTANT i3 -41838 CHECK-NEXT: [[K13:%[0-9]+]]:_(s3) = G_CONSTANT i3 -31839 CHECK-NEXT: [[K14:%[0-9]+]]:_(s3) = G_CONSTANT i3 -21840 CHECK-NEXT: [[IMPDEF1:%[0-9]+]]:_(s3) = G_IMPLICIT_DEF1841 CHECK-NEXT: [[MERGE4:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K8]]:_(s3), [[K9]]:_(s3), [[K10]]:_(s3)1842 CHECK-NEXT: [[MERGE5:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K11]]:_(s3), [[K12]]:_(s3), [[K13]]:_(s3)1843 CHECK-NEXT: [[MERGE6:%[0-9]+]]:_(s9) = G_MERGE_VALUES [[K14]]:_(s3), [[IMPDEF1]]:_(s3), [[IMPDEF1]]:_(s3)1844 CHECK-NEXT: [[MERGE7:%[0-9]+]]:_(s27) = G_MERGE_VALUES [[MERGE4]]:_(s9), [[MERGE5]]:_(s9), [[MERGE6]]:_(s9)1845 CHECK-NEXT: (s21) = G_TRUNC [[MERGE7]]:_(s27)1846 1847 1848 CHECK: [[K15:%[0-9]+]]:_(s8) = G_CONSTANT i8 01849 CHECK-NEXT: [[K16:%[0-9]+]]:_(s8) = G_CONSTANT i8 11850 CHECK-NEXT: [[ZEXT_K15:[0-9]+]]:_(s32) = G_ZEXT [[K15]]:_(s8)1851 CHECK-NEXT: [[ZEXT_K16:[0-9]+]]:_(s32) = G_ZEXT [[K16]]:_(s8)1852 [[K16:%[0-9]+]]:_(s32) = G_CONSTANT i32 81853 [[SHL:%[0-9]+]]:_(s32) = G_SHL [[ZEXT_K16]]:_, [[K16]]:_(s32)1854 [[OR:%[0-9]+]]:_(s32) = G_OR [[ZEXT_K16]]:_, [[SHL]]:_1855 (s16) = G_TRUNC [[OR]]:_(s32)1856 )";1857 1858 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1859}1860 1861TEST_F(AArch64GISelMITest, WidenScalarMergeValuesPointer) {1862 setUp();1863 if (!TM)1864 GTEST_SKIP();1865 1866 DefineLegalizerInfo(A, {});1867 1868 AInfo Info(MF->getSubtarget());1869 DummyGISelObserver Observer;1870 LegalizerHelper Helper(*MF, Info, Observer, B);1871 B.setInsertPt(*EntryMBB, EntryMBB->end());1872 1873 const LLT S32 = LLT::scalar(32);1874 const LLT S64 = LLT::scalar(64);1875 const LLT P0 = LLT::pointer(0, 64);1876 1877 auto Lo = B.buildTrunc(S32, Copies[0]);1878 auto Hi = B.buildTrunc(S32, Copies[1]);1879 1880 auto Merge = B.buildMergeLikeInstr(P0, {Lo, Hi});1881 1882 B.setInstr(*Merge);1883 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,1884 Helper.widenScalar(*Merge, 1, S64));1885 1886 auto CheckStr = R"(1887 CHECK: [[TRUNC0:%[0-9]+]]:_(s32) = G_TRUNC1888 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC1889 CHECK: [[ZEXT_TRUNC0:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC0]]1890 CHECK: [[ZEXT_TRUNC1:%[0-9]+]]:_(s64) = G_ZEXT [[TRUNC1]]1891 CHECK: [[SHIFT_AMT:%[0-9]+]]:_(s64) = G_CONSTANT i64 321892 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT_TRUNC1]]:_, [[SHIFT_AMT]]1893 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[ZEXT_TRUNC0]]:_, [[SHL]]1894 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]:_(s64)1895 )";1896 1897 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1898}1899 1900TEST_F(AArch64GISelMITest, WidenSEXTINREG) {1901 setUp();1902 if (!TM)1903 GTEST_SKIP();1904 1905 // Declare your legalization info1906 DefineLegalizerInfo(A, {1907 getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});1908 });1909 // Build Instr1910 auto MIB = B.buildInstr(1911 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},1912 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),1913 uint64_t(8)});1914 AInfo Info(MF->getSubtarget());1915 DummyGISelObserver Observer;1916 LegalizerHelper Helper(*MF, Info, Observer, B);1917 // Perform Legalization1918 B.setInstr(*MIB);1919 ASSERT_TRUE(Helper.widenScalar(*MIB, 0, LLT::scalar(64)) ==1920 LegalizerHelper::LegalizeResult::Legalized);1921 1922 auto CheckStr = R"(1923 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC1924 CHECK: [[T1:%[0-9]+]]:_(s64) = G_ANYEXT [[T0]]:_(s32)1925 CHECK: [[T2:%[0-9]+]]:_(s64) = G_SEXT_INREG [[T1]]:_, 81926 CHECK: [[T3:%[0-9]+]]:_(s32) = G_TRUNC [[T2]]:_(s64)1927 )";1928 1929 // Check1930 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1931}1932 1933TEST_F(AArch64GISelMITest, NarrowSEXTINREG) {1934 setUp();1935 if (!TM)1936 GTEST_SKIP();1937 1938 // Declare your legalization info, these aren't actually relevant to the test.1939 DefineLegalizerInfo(A, {1940 getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64});1941 });1942 // Build Instr1943 auto MIB = B.buildInstr(1944 TargetOpcode::G_SEXT_INREG, {LLT::scalar(16)},1945 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(16)}, {Copies[0]}),1946 uint64_t(8)});1947 AInfo Info(MF->getSubtarget());1948 DummyGISelObserver Observer;1949 LegalizerHelper Helper(*MF, Info, Observer, B);1950 // Perform Legalization1951 B.setInstr(*MIB);1952 ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(10)) ==1953 LegalizerHelper::LegalizeResult::Legalized);1954 1955 auto CheckStr = R"(1956 CHECK: [[T0:%[0-9]+]]:_(s16) = G_TRUNC1957 CHECK: [[T1:%[0-9]+]]:_(s10) = G_TRUNC [[T0]]:_(s16)1958 CHECK: [[T2:%[0-9]+]]:_(s10) = G_SEXT_INREG [[T1]]:_, 81959 CHECK: [[T3:%[0-9]+]]:_(s16) = G_SEXT [[T2]]:_(s10)1960 )";1961 1962 // Check1963 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;1964}1965 1966TEST_F(AArch64GISelMITest, NarrowSEXTINREG2) {1967 setUp();1968 if (!TM)1969 GTEST_SKIP();1970 1971 // Declare your legalization info, these aren't actually relevant to the test.1972 DefineLegalizerInfo(1973 A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });1974 // Build Instr1975 auto MIB = B.buildInstr(1976 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},1977 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),1978 uint64_t(9)});1979 AInfo Info(MF->getSubtarget());1980 DummyGISelObserver Observer;1981 LegalizerHelper Helper(*MF, Info, Observer, B);1982 // Perform Legalization1983 B.setInstr(*MIB);1984 ASSERT_TRUE(Helper.narrowScalar(*MIB, 0, LLT::scalar(8)) ==1985 LegalizerHelper::LegalizeResult::Legalized);1986 1987 auto CheckStr = R"(1988 CHECK: [[T0:%[0-9]+]]:_(s32) = G_TRUNC1989 CHECK: [[T1:%[0-9]+]]:_(s8), [[T2:%[0-9]+]]:_(s8), [[T3:%[0-9]+]]:_(s8), [[T4:%[0-9]+]]:_(s8) = G_UNMERGE_VALUES [[T0]]:_(s32)1990 CHECK: [[CST2:%[0-9]+]]:_(s8) = G_CONSTANT i8 71991 CHECK: [[T5:%[0-9]+]]:_(s8) = G_SEXT_INREG [[T2]]:_, 11992 CHECK: [[T6:%[0-9]+]]:_(s8) = G_ASHR [[T5]]:_, [[CST2]]:_1993 CHECK: [[T7:%[0-9]+]]:_(s32) = G_MERGE_VALUES [[T1]]:_(s8), [[T5]]:_(s8), [[T6]]:_(s8), [[T6]]:_(s8)1994 )";1995 1996 // Check1997 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));1998}1999 2000TEST_F(AArch64GISelMITest, LowerSEXTINREG) {2001 setUp();2002 if (!TM)2003 GTEST_SKIP();2004 2005 // Declare your legalization info, these aren't actually relevant to the test.2006 DefineLegalizerInfo(2007 A, { getActionDefinitionsBuilder(G_SEXT_INREG).legalForTypeWithAnyImm({s64}); });2008 // Build Instr2009 auto MIB = B.buildInstr(2010 TargetOpcode::G_SEXT_INREG, {LLT::scalar(32)},2011 {B.buildInstr(TargetOpcode::G_TRUNC, {LLT::scalar(32)}, {Copies[0]}),2012 uint64_t(8)});2013 AInfo Info(MF->getSubtarget());2014 DummyGISelObserver Observer;2015 LegalizerHelper Helper(*MF, Info, Observer, B);2016 // Perform Legalization2017 B.setInstr(*MIB);2018 ASSERT_TRUE(Helper.lower(*MIB, 0, LLT()) ==2019 LegalizerHelper::LegalizeResult::Legalized);2020 2021 auto CheckStr = R"(2022 CHECK: [[T1:%[0-9]+]]:_(s32) = G_TRUNC2023 CHECK: [[CST:%[0-9]+]]:_(s32) = G_CONSTANT i32 242024 CHECK: [[T2:%[0-9]+]]:_(s32) = G_SHL [[T1]]:_, [[CST]]:_2025 CHECK: [[T3:%[0-9]+]]:_(s32) = G_ASHR [[T2]]:_, [[CST]]:_2026 )";2027 2028 // Check2029 ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr));2030}2031 2032TEST_F(AArch64GISelMITest, LibcallFPExt) {2033 setUp();2034 if (!TM)2035 GTEST_SKIP();2036 2037 // Declare your legalization info2038 DefineLegalizerInfo(A, {2039 getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s32, s16}, {s128, s64}});2040 });2041 2042 LLT S16{LLT::scalar(16)};2043 LLT S32{LLT::scalar(32)};2044 LLT S128{LLT::scalar(128)};2045 auto MIBTrunc = B.buildTrunc(S16, Copies[0]);2046 auto MIBFPExt1 =2047 B.buildInstr(TargetOpcode::G_FPEXT, {S32}, {MIBTrunc});2048 2049 auto MIBFPExt2 =2050 B.buildInstr(TargetOpcode::G_FPEXT, {S128}, {Copies[1]});2051 AInfo Info(MF->getSubtarget());2052 DummyGISelObserver Observer;2053 LegalizerHelper Helper(*MF, Info, Observer, B);2054 LostDebugLocObserver DummyLocObserver("");2055 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2056 Helper.libcall(*MIBFPExt1, DummyLocObserver));2057 2058 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2059 Helper.libcall(*MIBFPExt2, DummyLocObserver));2060 auto CheckStr = R"(2061 CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC2062 CHECK: $h0 = COPY [[TRUNC]]2063 CHECK: BL &__extendhfsf22064 CHECK: $d0 = COPY2065 CHECK: BL &__extenddftf22066 )";2067 2068 // Check2069 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2070}2071 2072TEST_F(AArch64GISelMITest, LibcallFPTrunc) {2073 setUp();2074 if (!TM)2075 GTEST_SKIP();2076 2077 // Declare your legalization info2078 DefineLegalizerInfo(A, {2079 getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s16, s32}, {s64, s128}});2080 });2081 2082 LLT S16{LLT::scalar(16)};2083 LLT S32{LLT::scalar(32)};2084 LLT S64{LLT::scalar(64)};2085 LLT S128{LLT::scalar(128)};2086 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2087 auto MIBFPTrunc1 =2088 B.buildInstr(TargetOpcode::G_FPTRUNC, {S16}, {MIBTrunc});2089 2090 auto MIBMerge = B.buildMergeLikeInstr(S128, {Copies[1], Copies[2]});2091 2092 auto MIBFPTrunc2 =2093 B.buildInstr(TargetOpcode::G_FPTRUNC, {S64}, {MIBMerge});2094 AInfo Info(MF->getSubtarget());2095 DummyGISelObserver Observer;2096 LostDebugLocObserver DummyLocObserver("");2097 LegalizerHelper Helper(*MF, Info, Observer, B);2098 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2099 Helper.libcall(*MIBFPTrunc1, DummyLocObserver));2100 2101 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2102 Helper.libcall(*MIBFPTrunc2, DummyLocObserver));2103 auto CheckStr = R"(2104 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2105 CHECK: $s0 = COPY [[TRUNC]]2106 CHECK: BL &__truncsfhf22107 CHECK: $q0 = COPY2108 CHECK: BL &__trunctfdf22109 )";2110 2111 // Check2112 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2113}2114 2115TEST_F(AArch64GISelMITest, LibcallSimple) {2116 setUp();2117 if (!TM)2118 GTEST_SKIP();2119 2120 // Declare your legalization info2121 DefineLegalizerInfo(A, {2122 getActionDefinitionsBuilder(G_FADD).libcallFor({s16});2123 });2124 2125 LLT S16{LLT::scalar(16)};2126 auto MIBTrunc = B.buildTrunc(S16, Copies[0]);2127 auto MIBFADD =2128 B.buildInstr(TargetOpcode::G_FADD, {S16}, {MIBTrunc, MIBTrunc});2129 2130 AInfo Info(MF->getSubtarget());2131 DummyGISelObserver Observer;2132 LostDebugLocObserver DummyLocObserver("");2133 LegalizerHelper Helper(*MF, Info, Observer, B);2134 // Make sure we do not crash anymore2135 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,2136 Helper.libcall(*MIBFADD, DummyLocObserver));2137}2138 2139TEST_F(AArch64GISelMITest, LibcallMul) {2140 setUp();2141 if (!TM)2142 GTEST_SKIP();2143 2144 // Declare your legalization info2145 DefineLegalizerInfo(A, {2146 getActionDefinitionsBuilder(G_MUL).libcallFor({s32, s64, s128});2147 });2148 2149 LLT S32{LLT::scalar(32)};2150 LLT S64{LLT::scalar(64)};2151 LLT S128{LLT::scalar(128)};2152 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2153 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2154 2155 auto MIBMul32 =2156 B.buildInstr(TargetOpcode::G_MUL, {S32}, {MIBTrunc, MIBTrunc});2157 auto MIBMul64 =2158 B.buildInstr(TargetOpcode::G_MUL, {S64}, {Copies[0], Copies[0]});2159 auto MIBMul128 =2160 B.buildInstr(TargetOpcode::G_MUL, {S128}, {MIBExt, MIBExt});2161 2162 AInfo Info(MF->getSubtarget());2163 DummyGISelObserver Observer;2164 LostDebugLocObserver DummyLocObserver("");2165 LegalizerHelper Helper(*MF, Info, Observer, B);2166 2167 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2168 Helper.libcall(*MIBMul32, DummyLocObserver));2169 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2170 Helper.libcall(*MIBMul64, DummyLocObserver));2171 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2172 Helper.libcall(*MIBMul128, DummyLocObserver));2173 2174 auto CheckStr = R"(2175 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2176 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2177 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2178 CHECK: $w0 = COPY [[TRUNC]]2179 CHECK: $w1 = COPY [[TRUNC]]2180 CHECK: BL &__mulsi32181 CHECK: $x0 = COPY [[COPY]]2182 CHECK: $x1 = COPY [[COPY]]2183 CHECK: BL &__muldi32184 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2185 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2186 CHECK: $x0 = COPY [[UV]]2187 CHECK: $x1 = COPY [[UV1]]2188 CHECK: $x2 = COPY [[UV2]]2189 CHECK: $x3 = COPY [[UV3]]2190 CHECK: BL &__multi32191 )";2192 2193 // Check2194 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2195}2196 2197TEST_F(AArch64GISelMITest, LibcallSRem) {2198 setUp();2199 if (!TM)2200 GTEST_SKIP();2201 2202 // Declare your legalization info2203 DefineLegalizerInfo(A, {2204 getActionDefinitionsBuilder(G_SREM).libcallFor({s32, s64, s128});2205 });2206 2207 LLT S32{LLT::scalar(32)};2208 LLT S64{LLT::scalar(64)};2209 LLT S128{LLT::scalar(128)};2210 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2211 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2212 2213 auto MIBSRem32 =2214 B.buildInstr(TargetOpcode::G_SREM, {S32}, {MIBTrunc, MIBTrunc});2215 auto MIBSRem64 =2216 B.buildInstr(TargetOpcode::G_SREM, {S64}, {Copies[0], Copies[0]});2217 auto MIBSRem128 =2218 B.buildInstr(TargetOpcode::G_SREM, {S128}, {MIBExt, MIBExt});2219 2220 AInfo Info(MF->getSubtarget());2221 DummyGISelObserver Observer;2222 LostDebugLocObserver DummyLocObserver("");2223 LegalizerHelper Helper(*MF, Info, Observer, B);2224 2225 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2226 Helper.libcall(*MIBSRem32, DummyLocObserver));2227 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2228 Helper.libcall(*MIBSRem64, DummyLocObserver));2229 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2230 Helper.libcall(*MIBSRem128, DummyLocObserver));2231 2232 auto CheckStr = R"(2233 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2234 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2235 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2236 CHECK: $w0 = COPY [[TRUNC]]2237 CHECK: $w1 = COPY [[TRUNC]]2238 CHECK: BL &__modsi32239 CHECK: $x0 = COPY [[COPY]]2240 CHECK: $x1 = COPY [[COPY]]2241 CHECK: BL &__moddi32242 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2243 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2244 CHECK: $x0 = COPY [[UV]]2245 CHECK: $x1 = COPY [[UV1]]2246 CHECK: $x2 = COPY [[UV2]]2247 CHECK: $x3 = COPY [[UV3]]2248 CHECK: BL &__modti32249 )";2250 2251 // Check2252 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2253}2254 2255TEST_F(AArch64GISelMITest, LibcallURem) {2256 setUp();2257 if (!TM)2258 GTEST_SKIP();2259 2260 // Declare your legalization info2261 DefineLegalizerInfo(A, {2262 getActionDefinitionsBuilder(G_UREM).libcallFor({s32, s64, s128});2263 });2264 2265 LLT S32{LLT::scalar(32)};2266 LLT S64{LLT::scalar(64)};2267 LLT S128{LLT::scalar(128)};2268 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2269 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2270 2271 auto MIBURem32 =2272 B.buildInstr(TargetOpcode::G_UREM, {S32}, {MIBTrunc, MIBTrunc});2273 auto MIBURem64 =2274 B.buildInstr(TargetOpcode::G_UREM, {S64}, {Copies[0], Copies[0]});2275 auto MIBURem128 =2276 B.buildInstr(TargetOpcode::G_UREM, {S128}, {MIBExt, MIBExt});2277 2278 AInfo Info(MF->getSubtarget());2279 DummyGISelObserver Observer;2280 LostDebugLocObserver DummyLocObserver("");2281 LegalizerHelper Helper(*MF, Info, Observer, B);2282 2283 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2284 Helper.libcall(*MIBURem32, DummyLocObserver));2285 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2286 Helper.libcall(*MIBURem64, DummyLocObserver));2287 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2288 Helper.libcall(*MIBURem128, DummyLocObserver));2289 2290 const auto *CheckStr = R"(2291 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2292 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2293 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2294 CHECK: $w0 = COPY [[TRUNC]]2295 CHECK: $w1 = COPY [[TRUNC]]2296 CHECK: BL &__umodsi32297 CHECK: $x0 = COPY [[COPY]]2298 CHECK: $x1 = COPY [[COPY]]2299 CHECK: BL &__umoddi32300 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2301 CHECK: [[UV2:%[0-9]+]]:_(s64), [[UV3:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2302 CHECK: $x0 = COPY [[UV]]2303 CHECK: $x1 = COPY [[UV1]]2304 CHECK: $x2 = COPY [[UV2]]2305 CHECK: $x3 = COPY [[UV3]]2306 CHECK: BL &__umodti32307 )";2308 2309 // Check2310 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2311}2312 2313TEST_F(AArch64GISelMITest, LibcallCtlzZeroUndef) {2314 setUp();2315 if (!TM)2316 GTEST_SKIP();2317 2318 // Declare your legalization info2319 DefineLegalizerInfo(A, {2320 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)2321 .libcallFor({{s32, s32}, {s64, s64}, {s128, s128}});2322 });2323 2324 LLT S32{LLT::scalar(32)};2325 LLT S64{LLT::scalar(64)};2326 LLT S128{LLT::scalar(128)};2327 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2328 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2329 2330 auto MIBCtlz32 =2331 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S32}, {MIBTrunc});2332 auto MIBCtlz64 =2333 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S64}, {Copies[0]});2334 auto MIBCtlz128 =2335 B.buildInstr(TargetOpcode::G_CTLZ_ZERO_UNDEF, {S128}, {MIBExt});2336 2337 AInfo Info(MF->getSubtarget());2338 DummyGISelObserver Observer;2339 LostDebugLocObserver DummyLocObserver("");2340 LegalizerHelper Helper(*MF, Info, Observer, B);2341 2342 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2343 Helper.libcall(*MIBCtlz32, DummyLocObserver));2344 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2345 Helper.libcall(*MIBCtlz64, DummyLocObserver));2346 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2347 Helper.libcall(*MIBCtlz128, DummyLocObserver));2348 2349 const auto *CheckStr = R"(2350 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2351 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2352 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2353 CHECK: $w0 = COPY [[TRUNC]]2354 CHECK: BL &__clzsi22355 CHECK: $x0 = COPY [[COPY]]2356 CHECK: BL &__clzdi22357 CHECK: [[UV:%[0-9]+]]:_(s64), [[UV1:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT]]2358 CHECK: $x0 = COPY [[UV]]2359 CHECK: $x1 = COPY [[UV1]]2360 CHECK: BL &__clzti22361 )";2362 2363 // Check2364 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2365}2366 2367TEST_F(AArch64GISelMITest, LibcallFAdd) {2368 setUp();2369 if (!TM)2370 GTEST_SKIP();2371 2372 // Declare your legalization info2373 DefineLegalizerInfo(A, {2374 getActionDefinitionsBuilder(G_FADD).libcallFor({s32, s64, s128});2375 });2376 2377 LLT S32{LLT::scalar(32)};2378 LLT S64{LLT::scalar(64)};2379 LLT S128{LLT::scalar(128)};2380 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2381 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2382 2383 auto MIBAdd32 =2384 B.buildInstr(TargetOpcode::G_FADD, {S32}, {MIBTrunc, MIBTrunc});2385 auto MIBAdd64 =2386 B.buildInstr(TargetOpcode::G_FADD, {S64}, {Copies[0], Copies[0]});2387 auto MIBAdd128 = B.buildInstr(TargetOpcode::G_FADD, {S128}, {MIBExt, MIBExt});2388 2389 AInfo Info(MF->getSubtarget());2390 DummyGISelObserver Observer;2391 LostDebugLocObserver DummyLocObserver("");2392 LegalizerHelper Helper(*MF, Info, Observer, B);2393 2394 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2395 Helper.libcall(*MIBAdd32, DummyLocObserver));2396 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2397 Helper.libcall(*MIBAdd64, DummyLocObserver));2398 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2399 Helper.libcall(*MIBAdd128, DummyLocObserver));2400 2401 const auto *CheckStr = R"(2402 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2403 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2404 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2405 CHECK: $s0 = COPY [[TRUNC]]2406 CHECK: $s1 = COPY [[TRUNC]]2407 CHECK: BL &__addsf32408 CHECK: $d0 = COPY [[COPY]]2409 CHECK: $d1 = COPY [[COPY]]2410 CHECK: BL &__adddf32411 CHECK: $q0 = COPY [[ANYEXT]]2412 CHECK: $q1 = COPY [[ANYEXT]]2413 CHECK: BL &__addtf32414 )";2415 2416 // Check2417 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2418}2419 2420TEST_F(AArch64GISelMITest, LibcallFSub) {2421 setUp();2422 if (!TM)2423 GTEST_SKIP();2424 2425 // Declare your legalization info2426 DefineLegalizerInfo(A, {2427 getActionDefinitionsBuilder(G_FSUB).libcallFor({s32, s64, s128});2428 });2429 2430 LLT S32{LLT::scalar(32)};2431 LLT S64{LLT::scalar(64)};2432 LLT S128{LLT::scalar(128)};2433 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2434 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2435 2436 auto MIBSub32 =2437 B.buildInstr(TargetOpcode::G_FSUB, {S32}, {MIBTrunc, MIBTrunc});2438 auto MIBSub64 =2439 B.buildInstr(TargetOpcode::G_FSUB, {S64}, {Copies[0], Copies[0]});2440 auto MIBSub128 = B.buildInstr(TargetOpcode::G_FSUB, {S128}, {MIBExt, MIBExt});2441 2442 AInfo Info(MF->getSubtarget());2443 DummyGISelObserver Observer;2444 LostDebugLocObserver DummyLocObserver("");2445 LegalizerHelper Helper(*MF, Info, Observer, B);2446 2447 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2448 Helper.libcall(*MIBSub32, DummyLocObserver));2449 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2450 Helper.libcall(*MIBSub64, DummyLocObserver));2451 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2452 Helper.libcall(*MIBSub128, DummyLocObserver));2453 2454 const auto *CheckStr = R"(2455 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2456 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2457 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2458 CHECK: $s0 = COPY [[TRUNC]]2459 CHECK: $s1 = COPY [[TRUNC]]2460 CHECK: BL &__subsf32461 CHECK: $d0 = COPY [[COPY]]2462 CHECK: $d1 = COPY [[COPY]]2463 CHECK: BL &__subdf32464 CHECK: $q0 = COPY [[ANYEXT]]2465 CHECK: $q1 = COPY [[ANYEXT]]2466 CHECK: BL &__subtf32467 )";2468 2469 // Check2470 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2471}2472 2473TEST_F(AArch64GISelMITest, LibcallFMul) {2474 setUp();2475 if (!TM)2476 GTEST_SKIP();2477 2478 // Declare your legalization info2479 DefineLegalizerInfo(A, {2480 getActionDefinitionsBuilder(G_FMUL).libcallFor({s32, s64, s128});2481 });2482 2483 LLT S32{LLT::scalar(32)};2484 LLT S64{LLT::scalar(64)};2485 LLT S128{LLT::scalar(128)};2486 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2487 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2488 2489 auto MIBMul32 =2490 B.buildInstr(TargetOpcode::G_FMUL, {S32}, {MIBTrunc, MIBTrunc});2491 auto MIBMul64 =2492 B.buildInstr(TargetOpcode::G_FMUL, {S64}, {Copies[0], Copies[0]});2493 auto MIBMul128 = B.buildInstr(TargetOpcode::G_FMUL, {S128}, {MIBExt, MIBExt});2494 2495 AInfo Info(MF->getSubtarget());2496 DummyGISelObserver Observer;2497 LegalizerHelper Helper(*MF, Info, Observer, B);2498 LostDebugLocObserver DummyLocObserver("");2499 2500 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2501 Helper.libcall(*MIBMul32, DummyLocObserver));2502 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2503 Helper.libcall(*MIBMul64, DummyLocObserver));2504 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2505 Helper.libcall(*MIBMul128, DummyLocObserver));2506 2507 const auto *CheckStr = R"(2508 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2509 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2510 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2511 CHECK: $s0 = COPY [[TRUNC]]2512 CHECK: $s1 = COPY [[TRUNC]]2513 CHECK: BL &__mulsf32514 CHECK: $d0 = COPY [[COPY]]2515 CHECK: $d1 = COPY [[COPY]]2516 CHECK: BL &__muldf32517 CHECK: $q0 = COPY [[ANYEXT]]2518 CHECK: $q1 = COPY [[ANYEXT]]2519 CHECK: BL &__multf32520 )";2521 2522 // Check2523 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2524}2525 2526TEST_F(AArch64GISelMITest, LibcallFDiv) {2527 setUp();2528 if (!TM)2529 GTEST_SKIP();2530 2531 // Declare your legalization info2532 DefineLegalizerInfo(A, {2533 getActionDefinitionsBuilder(G_FDIV).libcallFor({s32, s64, s128});2534 });2535 2536 LLT S32{LLT::scalar(32)};2537 LLT S64{LLT::scalar(64)};2538 LLT S128{LLT::scalar(128)};2539 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2540 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2541 2542 auto MIBDiv32 =2543 B.buildInstr(TargetOpcode::G_FDIV, {S32}, {MIBTrunc, MIBTrunc});2544 auto MIBDiv64 =2545 B.buildInstr(TargetOpcode::G_FDIV, {S64}, {Copies[0], Copies[0]});2546 auto MIBDiv128 = B.buildInstr(TargetOpcode::G_FDIV, {S128}, {MIBExt, MIBExt});2547 2548 AInfo Info(MF->getSubtarget());2549 DummyGISelObserver Observer;2550 LostDebugLocObserver DummyLocObserver("");2551 LegalizerHelper Helper(*MF, Info, Observer, B);2552 2553 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2554 Helper.libcall(*MIBDiv32, DummyLocObserver));2555 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2556 Helper.libcall(*MIBDiv64, DummyLocObserver));2557 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2558 Helper.libcall(*MIBDiv128, DummyLocObserver));2559 2560 const auto *CheckStr = R"(2561 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2562 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2563 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2564 CHECK: $s0 = COPY [[TRUNC]]2565 CHECK: $s1 = COPY [[TRUNC]]2566 CHECK: BL &__divsf32567 CHECK: $d0 = COPY [[COPY]]2568 CHECK: $d1 = COPY [[COPY]]2569 CHECK: BL &__divdf32570 CHECK: $q0 = COPY [[ANYEXT]]2571 CHECK: $q1 = COPY [[ANYEXT]]2572 CHECK: BL &__divtf32573 )";2574 2575 // Check2576 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2577}2578 2579TEST_F(AArch64GISelMITest, LibcallFExp) {2580 setUp();2581 if (!TM)2582 GTEST_SKIP();2583 2584 // Declare your legalization info2585 DefineLegalizerInfo(A, {2586 getActionDefinitionsBuilder(G_FEXP).libcallFor({s32, s64, s128});2587 });2588 2589 LLT S32{LLT::scalar(32)};2590 LLT S64{LLT::scalar(64)};2591 LLT S128{LLT::scalar(128)};2592 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2593 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2594 2595 auto MIBExp32 = B.buildInstr(TargetOpcode::G_FEXP, {S32}, {MIBTrunc});2596 auto MIBExp64 = B.buildInstr(TargetOpcode::G_FEXP, {S64}, {Copies[0]});2597 auto MIBExp128 = B.buildInstr(TargetOpcode::G_FEXP, {S128}, {MIBExt});2598 2599 AInfo Info(MF->getSubtarget());2600 DummyGISelObserver Observer;2601 LostDebugLocObserver DummyLocObserver("");2602 LegalizerHelper Helper(*MF, Info, Observer, B);2603 2604 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2605 Helper.libcall(*MIBExp32, DummyLocObserver));2606 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2607 Helper.libcall(*MIBExp64, DummyLocObserver));2608 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2609 Helper.libcall(*MIBExp128, DummyLocObserver));2610 2611 const auto *CheckStr = R"(2612 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2613 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2614 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2615 CHECK: $s0 = COPY [[TRUNC]]2616 CHECK: BL &expf2617 CHECK: $d0 = COPY [[COPY]]2618 CHECK: BL &exp2619 CHECK: $q0 = COPY [[ANYEXT]]2620 CHECK: BL &expl2621 )";2622 2623 // Check2624 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2625}2626 2627TEST_F(AArch64GISelMITest, LibcallFExp2) {2628 setUp();2629 if (!TM)2630 GTEST_SKIP();2631 2632 // Declare your legalization info2633 DefineLegalizerInfo(A, {2634 getActionDefinitionsBuilder(G_FEXP2).libcallFor({s32, s64, s128});2635 });2636 2637 LLT S32{LLT::scalar(32)};2638 LLT S64{LLT::scalar(64)};2639 LLT S128{LLT::scalar(128)};2640 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2641 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2642 2643 auto MIBExp232 = B.buildInstr(TargetOpcode::G_FEXP2, {S32}, {MIBTrunc});2644 auto MIBExp264 = B.buildInstr(TargetOpcode::G_FEXP2, {S64}, {Copies[0]});2645 auto MIBExp2128 = B.buildInstr(TargetOpcode::G_FEXP2, {S128}, {MIBExt});2646 2647 AInfo Info(MF->getSubtarget());2648 DummyGISelObserver Observer;2649 LostDebugLocObserver DummyLocObserver("");2650 LegalizerHelper Helper(*MF, Info, Observer, B);2651 2652 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2653 Helper.libcall(*MIBExp232, DummyLocObserver));2654 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2655 Helper.libcall(*MIBExp264, DummyLocObserver));2656 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2657 Helper.libcall(*MIBExp2128, DummyLocObserver));2658 2659 const auto *CheckStr = R"(2660 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2661 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2662 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2663 CHECK: $s0 = COPY [[TRUNC]]2664 CHECK: BL &exp2f2665 CHECK: $d0 = COPY [[COPY]]2666 CHECK: BL &exp22667 CHECK: $q0 = COPY [[ANYEXT]]2668 CHECK: BL &exp2l2669 )";2670 2671 // Check2672 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2673}2674 2675TEST_F(AArch64GISelMITest, LibcallFRem) {2676 setUp();2677 if (!TM)2678 GTEST_SKIP();2679 2680 // Declare your legalization info2681 DefineLegalizerInfo(A, {2682 getActionDefinitionsBuilder(G_FREM).libcallFor({s32, s64, s128});2683 });2684 2685 LLT S32{LLT::scalar(32)};2686 LLT S64{LLT::scalar(64)};2687 LLT S128{LLT::scalar(128)};2688 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2689 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2690 2691 auto MIBFRem32 = B.buildInstr(TargetOpcode::G_FREM, {S32}, {MIBTrunc});2692 auto MIBFRem64 = B.buildInstr(TargetOpcode::G_FREM, {S64}, {Copies[0]});2693 auto MIBFRem128 = B.buildInstr(TargetOpcode::G_FREM, {S128}, {MIBExt});2694 2695 AInfo Info(MF->getSubtarget());2696 DummyGISelObserver Observer;2697 LostDebugLocObserver DummyLocObserver("");2698 LegalizerHelper Helper(*MF, Info, Observer, B);2699 2700 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2701 Helper.libcall(*MIBFRem32, DummyLocObserver));2702 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2703 Helper.libcall(*MIBFRem64, DummyLocObserver));2704 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2705 Helper.libcall(*MIBFRem128, DummyLocObserver));2706 2707 const auto *CheckStr = R"(2708 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2709 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2710 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2711 CHECK: $s0 = COPY [[TRUNC]]2712 CHECK: BL &fmodf2713 CHECK: $d0 = COPY [[COPY]]2714 CHECK: BL &fmod2715 CHECK: $q0 = COPY [[ANYEXT]]2716 CHECK: BL &fmodl2717 )";2718 2719 // Check2720 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2721}2722 2723TEST_F(AArch64GISelMITest, LibcallFPow) {2724 setUp();2725 if (!TM)2726 GTEST_SKIP();2727 2728 // Declare your legalization info2729 DefineLegalizerInfo(A, {2730 getActionDefinitionsBuilder(G_FPOW).libcallFor({s32, s64, s128});2731 });2732 2733 LLT S32{LLT::scalar(32)};2734 LLT S64{LLT::scalar(64)};2735 LLT S128{LLT::scalar(128)};2736 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2737 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2738 2739 auto MIBPow32 = B.buildInstr(TargetOpcode::G_FPOW, {S32}, {MIBTrunc});2740 auto MIBPow64 = B.buildInstr(TargetOpcode::G_FPOW, {S64}, {Copies[0]});2741 auto MIBPow128 = B.buildInstr(TargetOpcode::G_FPOW, {S128}, {MIBExt});2742 2743 AInfo Info(MF->getSubtarget());2744 DummyGISelObserver Observer;2745 LostDebugLocObserver DummyLocObserver("");2746 LegalizerHelper Helper(*MF, Info, Observer, B);2747 2748 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2749 Helper.libcall(*MIBPow32, DummyLocObserver));2750 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2751 Helper.libcall(*MIBPow64, DummyLocObserver));2752 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2753 Helper.libcall(*MIBPow128, DummyLocObserver));2754 2755 const auto *CheckStr = R"(2756 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2757 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2758 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2759 CHECK: $s0 = COPY [[TRUNC]]2760 CHECK: BL &powf2761 CHECK: $d0 = COPY [[COPY]]2762 CHECK: BL &pow2763 CHECK: $q0 = COPY [[ANYEXT]]2764 CHECK: BL &powl2765 )";2766 2767 // Check2768 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2769}2770 2771TEST_F(AArch64GISelMITest, LibcallFMa) {2772 setUp();2773 if (!TM)2774 GTEST_SKIP();2775 2776 // Declare your legalization info2777 DefineLegalizerInfo(A, {2778 getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64, s128});2779 });2780 2781 LLT S32{LLT::scalar(32)};2782 LLT S64{LLT::scalar(64)};2783 LLT S128{LLT::scalar(128)};2784 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2785 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2786 2787 auto MIBMa32 = B.buildInstr(TargetOpcode::G_FMA, {S32}, {MIBTrunc, MIBTrunc});2788 auto MIBMa64 =2789 B.buildInstr(TargetOpcode::G_FMA, {S64}, {Copies[0], Copies[0]});2790 auto MIBMa128 = B.buildInstr(TargetOpcode::G_FMA, {S128}, {MIBExt, MIBExt});2791 2792 AInfo Info(MF->getSubtarget());2793 DummyGISelObserver Observer;2794 LostDebugLocObserver DummyLocObserver("");2795 LegalizerHelper Helper(*MF, Info, Observer, B);2796 2797 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2798 Helper.libcall(*MIBMa32, DummyLocObserver));2799 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2800 Helper.libcall(*MIBMa64, DummyLocObserver));2801 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2802 Helper.libcall(*MIBMa128, DummyLocObserver));2803 2804 const auto *CheckStr = R"(2805 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2806 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2807 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2808 CHECK: $s0 = COPY [[TRUNC]]2809 CHECK: BL &fmaf2810 CHECK: $d0 = COPY [[COPY]]2811 CHECK: BL &fma2812 CHECK: $q0 = COPY [[ANYEXT]]2813 CHECK: BL &fmal2814 )";2815 2816 // Check2817 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2818}2819 2820TEST_F(AArch64GISelMITest, LibcallFCeil) {2821 setUp();2822 if (!TM)2823 GTEST_SKIP();2824 2825 // Declare your legalization info2826 DefineLegalizerInfo(A, {2827 getActionDefinitionsBuilder(G_FCEIL).libcallFor({s32, s64, s128});2828 });2829 2830 LLT S32{LLT::scalar(32)};2831 LLT S64{LLT::scalar(64)};2832 LLT S128{LLT::scalar(128)};2833 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2834 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2835 2836 auto MIBCeil32 = B.buildInstr(TargetOpcode::G_FCEIL, {S32}, {MIBTrunc});2837 auto MIBCeil64 = B.buildInstr(TargetOpcode::G_FCEIL, {S64}, {Copies[0]});2838 auto MIBCeil128 = B.buildInstr(TargetOpcode::G_FCEIL, {S128}, {MIBExt});2839 2840 AInfo Info(MF->getSubtarget());2841 DummyGISelObserver Observer;2842 LegalizerHelper Helper(*MF, Info, Observer, B);2843 LostDebugLocObserver DummyLocObserver("");2844 2845 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2846 Helper.libcall(*MIBCeil32, DummyLocObserver));2847 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2848 Helper.libcall(*MIBCeil64, DummyLocObserver));2849 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2850 Helper.libcall(*MIBCeil128, DummyLocObserver));2851 2852 const auto *CheckStr = R"(2853 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2854 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2855 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2856 CHECK: $s0 = COPY [[TRUNC]]2857 CHECK: BL &ceilf2858 CHECK: $d0 = COPY [[COPY]]2859 CHECK: BL &ceil2860 CHECK: $q0 = COPY [[ANYEXT]]2861 CHECK: BL &ceill2862 )";2863 2864 // Check2865 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2866}2867 2868TEST_F(AArch64GISelMITest, LibcallFFloor) {2869 setUp();2870 if (!TM)2871 GTEST_SKIP();2872 2873 // Declare your legalization info2874 DefineLegalizerInfo(A, {2875 getActionDefinitionsBuilder(G_FFLOOR).libcallFor({s32, s64, s128});2876 });2877 2878 LLT S32{LLT::scalar(32)};2879 LLT S64{LLT::scalar(64)};2880 LLT S128{LLT::scalar(128)};2881 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2882 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2883 2884 auto MIBFloor32 = B.buildInstr(TargetOpcode::G_FFLOOR, {S32}, {MIBTrunc});2885 auto MIBFloor64 = B.buildInstr(TargetOpcode::G_FFLOOR, {S64}, {Copies[0]});2886 auto MIBFloor128 = B.buildInstr(TargetOpcode::G_FFLOOR, {S128}, {MIBExt});2887 2888 AInfo Info(MF->getSubtarget());2889 DummyGISelObserver Observer;2890 LegalizerHelper Helper(*MF, Info, Observer, B);2891 LostDebugLocObserver DummyLocObserver("");2892 2893 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2894 Helper.libcall(*MIBFloor32, DummyLocObserver));2895 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2896 Helper.libcall(*MIBFloor64, DummyLocObserver));2897 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2898 Helper.libcall(*MIBFloor128, DummyLocObserver));2899 2900 const auto *CheckStr = R"(2901 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2902 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2903 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2904 CHECK: $s0 = COPY [[TRUNC]]2905 CHECK: BL &floorf2906 CHECK: $d0 = COPY [[COPY]]2907 CHECK: BL &floor2908 CHECK: $q0 = COPY [[ANYEXT]]2909 CHECK: BL &floorl2910 )";2911 2912 // Check2913 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2914}2915 2916TEST_F(AArch64GISelMITest, LibcallFMinNum) {2917 setUp();2918 if (!TM)2919 GTEST_SKIP();2920 2921 // Declare your legalization info2922 DefineLegalizerInfo(A, {2923 getActionDefinitionsBuilder(G_FMINNUM).libcallFor({s32, s64, s128});2924 });2925 2926 LLT S32{LLT::scalar(32)};2927 LLT S64{LLT::scalar(64)};2928 LLT S128{LLT::scalar(128)};2929 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2930 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2931 2932 auto MIBMin32 = B.buildFMinNum(S32, MIBTrunc, MIBTrunc);2933 auto MIBMin64 = B.buildFMinNum(S64, Copies[0], Copies[0]);2934 auto MIBMin128 = B.buildFMinNum(S128, MIBExt, MIBExt);2935 2936 AInfo Info(MF->getSubtarget());2937 DummyGISelObserver Observer;2938 LegalizerHelper Helper(*MF, Info, Observer, B);2939 LostDebugLocObserver DummyLocObserver("");2940 2941 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2942 Helper.libcall(*MIBMin32, DummyLocObserver));2943 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2944 Helper.libcall(*MIBMin64, DummyLocObserver));2945 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2946 Helper.libcall(*MIBMin128, DummyLocObserver));2947 2948 const auto *CheckStr = R"(2949 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY2950 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC2951 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT2952 CHECK: $s0 = COPY [[TRUNC]]2953 CHECK: $s1 = COPY [[TRUNC]]2954 CHECK: BL &fminf2955 CHECK: $d0 = COPY [[COPY]]2956 CHECK: $d1 = COPY [[COPY]]2957 CHECK: BL &fmin2958 CHECK: $q0 = COPY [[ANYEXT]]2959 CHECK: $q1 = COPY [[ANYEXT]]2960 CHECK: BL &fminl2961 )";2962 2963 // Check2964 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;2965}2966 2967TEST_F(AArch64GISelMITest, LibcallFMaxNum) {2968 setUp();2969 if (!TM)2970 GTEST_SKIP();2971 2972 // Declare your legalization info2973 DefineLegalizerInfo(A, {2974 getActionDefinitionsBuilder(G_FMAXNUM).libcallFor({s32, s64, s128});2975 });2976 2977 LLT S32{LLT::scalar(32)};2978 LLT S64{LLT::scalar(64)};2979 LLT S128{LLT::scalar(128)};2980 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);2981 auto MIBExt = B.buildAnyExt(S128, Copies[0]);2982 2983 auto MIBMax32 = B.buildFMaxNum(S32, MIBTrunc, MIBTrunc);2984 auto MIBMax64 = B.buildFMaxNum(S64, Copies[0], Copies[0]);2985 auto MIBMax128 = B.buildFMaxNum(S128, MIBExt, MIBExt);2986 2987 AInfo Info(MF->getSubtarget());2988 DummyGISelObserver Observer;2989 LegalizerHelper Helper(*MF, Info, Observer, B);2990 LostDebugLocObserver DummyLocObserver("");2991 2992 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2993 Helper.libcall(*MIBMax32, DummyLocObserver));2994 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2995 Helper.libcall(*MIBMax64, DummyLocObserver));2996 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,2997 Helper.libcall(*MIBMax128, DummyLocObserver));2998 2999 const auto *CheckStr = R"(3000 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3001 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC3002 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT3003 CHECK: $s0 = COPY [[TRUNC]]3004 CHECK: $s1 = COPY [[TRUNC]]3005 CHECK: BL &fmaxf3006 CHECK: $d0 = COPY [[COPY]]3007 CHECK: $d1 = COPY [[COPY]]3008 CHECK: BL &fmax3009 CHECK: $q0 = COPY [[ANYEXT]]3010 CHECK: $q1 = COPY [[ANYEXT]]3011 CHECK: BL &fmaxl3012 )";3013 3014 // Check3015 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3016}3017 3018TEST_F(AArch64GISelMITest, LibcallFSqrt) {3019 setUp();3020 if (!TM)3021 GTEST_SKIP();3022 3023 // Declare your legalization info3024 DefineLegalizerInfo(A, {3025 getActionDefinitionsBuilder(G_FSQRT).libcallFor({s32, s64, s128});3026 });3027 3028 LLT S32{LLT::scalar(32)};3029 LLT S64{LLT::scalar(64)};3030 LLT S128{LLT::scalar(128)};3031 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);3032 auto MIBExt = B.buildAnyExt(S128, Copies[0]);3033 3034 auto MIBSqrt32 = B.buildInstr(TargetOpcode::G_FSQRT, {S32}, {MIBTrunc});3035 auto MIBSqrt64 = B.buildInstr(TargetOpcode::G_FSQRT, {S64}, {Copies[0]});3036 auto MIBSqrt128 = B.buildInstr(TargetOpcode::G_FSQRT, {S128}, {MIBExt});3037 3038 AInfo Info(MF->getSubtarget());3039 DummyGISelObserver Observer;3040 LegalizerHelper Helper(*MF, Info, Observer, B);3041 LostDebugLocObserver DummyLocObserver("");3042 3043 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3044 Helper.libcall(*MIBSqrt32, DummyLocObserver));3045 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3046 Helper.libcall(*MIBSqrt64, DummyLocObserver));3047 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3048 Helper.libcall(*MIBSqrt128, DummyLocObserver));3049 3050 const auto *CheckStr = R"(3051 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3052 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC3053 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT3054 CHECK: $s0 = COPY [[TRUNC]]3055 CHECK: BL &sqrtf3056 CHECK: $d0 = COPY [[COPY]]3057 CHECK: BL &sqrt3058 CHECK: $q0 = COPY [[ANYEXT]]3059 CHECK: BL &sqrtl3060 )";3061 3062 // Check3063 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3064}3065 3066TEST_F(AArch64GISelMITest, LibcallFRint) {3067 setUp();3068 if (!TM)3069 GTEST_SKIP();3070 3071 // Declare your legalization info3072 DefineLegalizerInfo(A, {3073 getActionDefinitionsBuilder(G_FRINT).libcallFor({s32, s64, s128});3074 });3075 3076 LLT S32{LLT::scalar(32)};3077 LLT S64{LLT::scalar(64)};3078 LLT S128{LLT::scalar(128)};3079 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);3080 auto MIBExt = B.buildAnyExt(S128, Copies[0]);3081 3082 auto MIBRint32 = B.buildInstr(TargetOpcode::G_FRINT, {S32}, {MIBTrunc});3083 auto MIBRint64 = B.buildInstr(TargetOpcode::G_FRINT, {S64}, {Copies[0]});3084 auto MIBRint128 = B.buildInstr(TargetOpcode::G_FRINT, {S128}, {MIBExt});3085 3086 AInfo Info(MF->getSubtarget());3087 DummyGISelObserver Observer;3088 LegalizerHelper Helper(*MF, Info, Observer, B);3089 LostDebugLocObserver DummyLocObserver("");3090 3091 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3092 Helper.libcall(*MIBRint32, DummyLocObserver));3093 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3094 Helper.libcall(*MIBRint64, DummyLocObserver));3095 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3096 Helper.libcall(*MIBRint128, DummyLocObserver));3097 3098 const auto *CheckStr = R"(3099 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3100 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC3101 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT3102 CHECK: $s0 = COPY [[TRUNC]]3103 CHECK: BL &rintf3104 CHECK: $d0 = COPY [[COPY]]3105 CHECK: BL &rint3106 CHECK: $q0 = COPY [[ANYEXT]]3107 CHECK: BL &rintl3108 )";3109 3110 // Check3111 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3112}3113 3114TEST_F(AArch64GISelMITest, LibcallFNearbyInt) {3115 setUp();3116 if (!TM)3117 GTEST_SKIP();3118 3119 // Declare your legalization info3120 DefineLegalizerInfo(A, {3121 getActionDefinitionsBuilder(G_FNEARBYINT).libcallFor({s32, s64, s128});3122 });3123 3124 LLT S32{LLT::scalar(32)};3125 LLT S64{LLT::scalar(64)};3126 LLT S128{LLT::scalar(128)};3127 auto MIBTrunc = B.buildTrunc(S32, Copies[0]);3128 auto MIBExt = B.buildAnyExt(S128, Copies[0]);3129 3130 auto MIBNearbyInt32 =3131 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S32}, {MIBTrunc});3132 auto MIBNearbyInt64 =3133 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S64}, {Copies[0]});3134 auto MIBNearbyInt128 =3135 B.buildInstr(TargetOpcode::G_FNEARBYINT, {S128}, {MIBExt});3136 3137 AInfo Info(MF->getSubtarget());3138 DummyGISelObserver Observer;3139 LegalizerHelper Helper(*MF, Info, Observer, B);3140 LostDebugLocObserver DummyLocObserver("");3141 3142 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3143 Helper.libcall(*MIBNearbyInt32, DummyLocObserver));3144 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3145 Helper.libcall(*MIBNearbyInt64, DummyLocObserver));3146 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3147 Helper.libcall(*MIBNearbyInt128, DummyLocObserver));3148 3149 const auto *CheckStr = R"(3150 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3151 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC3152 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT3153 CHECK: $s0 = COPY [[TRUNC]]3154 CHECK: BL &nearbyintf3155 CHECK: $d0 = COPY [[COPY]]3156 CHECK: BL &nearbyint3157 CHECK: $q0 = COPY [[ANYEXT]]3158 CHECK: BL &nearbyintl3159 )";3160 3161 // Check3162 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3163}3164 3165TEST_F(AArch64GISelMITest, NarrowScalarExtract) {3166 setUp();3167 if (!TM)3168 GTEST_SKIP();3169 3170 // Declare your legalization info3171 DefineLegalizerInfo(A, {3172 getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});3173 getActionDefinitionsBuilder(G_EXTRACT).legalForTypeWithAnyImm({{s16, s32}});3174 });3175 3176 LLT S16{LLT::scalar(16)};3177 LLT S32{LLT::scalar(32)};3178 3179 auto MIBExtractS32 = B.buildExtract(S32, Copies[1], 32);3180 auto MIBExtractS16 = B.buildExtract(S16, Copies[1], 0);3181 3182 AInfo Info(MF->getSubtarget());3183 DummyGISelObserver Observer;3184 LegalizerHelper Helper(*MF, Info, Observer, B);3185 3186 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3187 Helper.narrowScalar(*MIBExtractS32, 1, S32));3188 3189 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3190 Helper.narrowScalar(*MIBExtractS16, 1, S32));3191 3192 const auto *CheckStr = R"(3193 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES3194 CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[UV1]]3195 CHECK: [[UV3:%[0-9]+]]:_(s32), [[UV4:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES3196 CHECK: [[EXTR:%[0-9]+]]:_(s16) = G_EXTRACT [[UV3]]:_(s32), 03197 CHECK: [[COPY:%[0-9]+]]:_(s16) = COPY [[EXTR]]3198 )";3199 3200 // Check3201 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3202}3203 3204TEST_F(AArch64GISelMITest, LowerInsert) {3205 setUp();3206 if (!TM)3207 GTEST_SKIP();3208 3209 // Declare your legalization info3210 DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_INSERT).lower(); });3211 3212 LLT S32{LLT::scalar(32)};3213 LLT S64{LLT::scalar(64)};3214 LLT P0{LLT::pointer(0, 64)};3215 LLT P1{LLT::pointer(1, 32)};3216 LLT V2S32{LLT::fixed_vector(2, 32)};3217 3218 auto TruncS32 = B.buildTrunc(S32, Copies[0]);3219 auto IntToPtrP0 = B.buildIntToPtr(P0, Copies[0]);3220 auto IntToPtrP1 = B.buildIntToPtr(P1, TruncS32);3221 auto BitcastV2S32 = B.buildBitcast(V2S32, Copies[0]);3222 3223 auto InsertS64S32 = B.buildInsert(S64, Copies[0], TruncS32, 0);3224 auto InsertS64P1 = B.buildInsert(S64, Copies[0], IntToPtrP1, 8);3225 auto InsertP0S32 = B.buildInsert(P0, IntToPtrP0, TruncS32, 16);3226 auto InsertP0P1 = B.buildInsert(P0, IntToPtrP0, IntToPtrP1, 4);3227 auto InsertV2S32S32 = B.buildInsert(V2S32, BitcastV2S32, TruncS32, 32);3228 auto InsertV2S32P1 = B.buildInsert(V2S32, BitcastV2S32, IntToPtrP1, 0);3229 3230 AInfo Info(MF->getSubtarget());3231 DummyGISelObserver Observer;3232 LegalizerHelper Helper(*MF, Info, Observer, B);3233 3234 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3235 Helper.lower(*InsertS64S32, 0, LLT{}));3236 3237 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3238 Helper.lower(*InsertS64P1, 0, LLT{}));3239 3240 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3241 Helper.lower(*InsertP0S32, 0, LLT{}));3242 3243 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3244 Helper.lower(*InsertP0P1, 0, LLT{}));3245 3246 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3247 Helper.lower(*InsertV2S32S32, 0, LLT{}));3248 3249 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,3250 Helper.lower(*InsertV2S32P1, 0, LLT{}));3251 3252 const auto *CheckStr = R"(3253 CHECK: [[S64:%[0-9]+]]:_(s64) = COPY3254 CHECK: [[S32:%[0-9]+]]:_(s32) = G_TRUNC [[S64]]3255 CHECK: [[P0:%[0-9]+]]:_(p0) = G_INTTOPTR [[S64]]3256 CHECK: [[P1:%[0-9]+]]:_(p1) = G_INTTOPTR [[S32]]3257 CHECK: [[V2S32:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[S64]]3258 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]3259 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3260 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_3261 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[ZEXT]]:_3262 3263 CHECK: [[PTRTOINT:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]3264 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT]]3265 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3266 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)3267 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3268 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[S64]]:_, [[C]]:_3269 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_3270 3271 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]3272 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[S32]]3273 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3274 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)3275 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3276 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_3277 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_3278 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]3279 3280 CHECK: [[PTRTOINT:%[0-9]+]]:_(s64) = G_PTRTOINT [[P0]]3281 CHECK: [[PTRTOINT1:%[0-9]+]]:_(s32) = G_PTRTOINT [[P1]]3282 CHECK: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT [[PTRTOINT1]]3283 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3284 CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ZEXT]]:_, [[C]]:_(s64)3285 CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT3286 CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[PTRTOINT]]:_, [[C]]:_3287 CHECK: [[OR:%[0-9]+]]:_(s64) = G_OR [[AND]]:_, [[SHL]]:_3288 CHECK: [[INTTOPTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[OR]]3289 3290 CHECK: [[V2S32_E0:%[0-9]+]]:_(s32), [[V2S32_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[V2S32]]3291 CHECK: [[BV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[V2S32_E0]]:_(s32), [[S32]]:_(s32)3292 )";3293 3294 // Check3295 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3296}3297 3298// Test lowering of G_FFLOOR3299TEST_F(AArch64GISelMITest, LowerFFloor) {3300 setUp();3301 if (!TM)3302 GTEST_SKIP();3303 3304 // Declare your legalization info3305 DefineLegalizerInfo(A, {});3306 // Build Instr3307 auto Floor = B.buildFFloor(LLT::scalar(64), Copies[0], MachineInstr::MIFlag::FmNoInfs);3308 AInfo Info(MF->getSubtarget());3309 DummyGISelObserver Observer;3310 LegalizerHelper Helper(*MF, Info, Observer, B);3311 // Perform Legalization3312 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3313 Helper.lower(*Floor, 0, LLT()));3314 3315 auto CheckStr = R"(3316 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3317 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = ninf G_INTRINSIC_TRUNC [[COPY]]3318 CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_FCONSTANT double 0.000000e+003319 CHECK: [[CMP0:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(olt), [[COPY]]:_(s64), [[ZERO]]:_3320 CHECK: [[CMP1:%[0-9]+]]:_(s1) = ninf G_FCMP floatpred(one), [[COPY]]:_(s64), [[TRUNC]]:_3321 CHECK: [[AND:%[0-9]+]]:_(s1) = G_AND [[CMP0]]:_, [[CMP1]]:_3322 CHECK: [[ITOFP:%[0-9]+]]:_(s64) = G_SITOFP [[AND]]3323 = ninf G_FADD [[TRUNC]]:_, [[ITOFP]]:_3324 )";3325 3326 // Check3327 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3328}3329 3330// Test lowering of G_BSWAP3331TEST_F(AArch64GISelMITest, LowerBSWAP) {3332 setUp();3333 if (!TM)3334 GTEST_SKIP();3335 3336 DefineLegalizerInfo(A, {});3337 3338 // Make sure vector lowering doesn't assert.3339 auto Cast = B.buildBitcast(LLT::fixed_vector(2, 32), Copies[0]);3340 auto BSwap = B.buildBSwap(LLT::fixed_vector(2, 32), Cast);3341 AInfo Info(MF->getSubtarget());3342 DummyGISelObserver Observer;3343 LegalizerHelper Helper(*MF, Info, Observer, B);3344 // Perform Legalization3345 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3346 Helper.lower(*BSwap, 0, LLT()));3347 3348 auto CheckStr = R"(3349 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3350 CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]3351 CHECK: [[K24:%[0-9]+]]:_(s32) = G_CONSTANT i32 243352 CHECK: [[SPLAT24:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K24]]:_(s32), [[K24]]:_(s32)3353 CHECK: [[SHL0:%[0-9]+]]:_(<2 x s32>) = G_SHL [[VEC]]:_, [[SPLAT24]]3354 CHECK: [[SHR0:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT24]]3355 CHECK: [[OR0:%[0-9]+]]:_(<2 x s32>) = G_OR [[SHR0]]:_, [[SHL0]]:_3356 CHECK: [[KMASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 652803357 CHECK: [[SPLATMASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[KMASK]]:_(s32), [[KMASK]]:_(s32)3358 CHECK: [[K8:%[0-9]+]]:_(s32) = G_CONSTANT i32 83359 CHECK: [[SPLAT8:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[K8]]:_(s32), [[K8]]:_(s32)3360 CHECK: [[AND0:%[0-9]+]]:_(<2 x s32>) = G_AND [[VEC]]:_, [[SPLATMASK]]:_3361 CHECK: [[SHL1:%[0-9]+]]:_(<2 x s32>) = G_SHL [[AND0]]:_, [[SPLAT8]]3362 CHECK: [[OR1:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR0]]:_, [[SHL1]]:_3363 CHECK: [[SHR1:%[0-9]+]]:_(<2 x s32>) = G_LSHR [[VEC]]:_, [[SPLAT8]]3364 CHECK: [[AND1:%[0-9]+]]:_(<2 x s32>) = G_AND [[SHR1]]:_, [[SPLATMASK]]:_3365 CHECK: [[BSWAP:%[0-9]+]]:_(<2 x s32>) = G_OR [[OR1]]:_, [[AND1]]:_3366 )";3367 3368 // Check3369 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3370}3371 3372// Test lowering of G_SDIVREM into G_SDIV and G_SREM3373TEST_F(AArch64GISelMITest, LowerSDIVREM) {3374 setUp();3375 if (!TM)3376 GTEST_SKIP();3377 3378 // Declare your legalization info3379 DefineLegalizerInfo(3380 A, { getActionDefinitionsBuilder(G_SDIVREM).lowerFor({s64}); });3381 3382 LLT S64{LLT::scalar(64)};3383 3384 // Build Instr3385 auto SDivrem =3386 B.buildInstr(TargetOpcode::G_SDIVREM, {S64, S64}, {Copies[0], Copies[1]});3387 AInfo Info(MF->getSubtarget());3388 DummyGISelObserver Observer;3389 LegalizerHelper Helper(*MF, Info, Observer, B);3390 // Perform Legalization3391 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3392 Helper.lower(*SDivrem, 0, S64));3393 3394 const auto *CheckStr = R"(3395 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_SDIV %0:_, %1:_3396 CHECK: [[REM:%[0-9]+]]:_(s64) = G_SREM %0:_, %1:_3397 )";3398 3399 // Check3400 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3401}3402 3403// Test lowering of G_UDIVREM into G_UDIV and G_UREM3404TEST_F(AArch64GISelMITest, LowerUDIVREM) {3405 setUp();3406 if (!TM)3407 GTEST_SKIP();3408 3409 // Declare your legalization info3410 DefineLegalizerInfo(3411 A, { getActionDefinitionsBuilder(G_UDIVREM).lowerFor({s64}); });3412 3413 LLT S64{LLT::scalar(64)};3414 3415 // Build Instr3416 auto UDivrem =3417 B.buildInstr(TargetOpcode::G_UDIVREM, {S64, S64}, {Copies[0], Copies[1]});3418 AInfo Info(MF->getSubtarget());3419 DummyGISelObserver Observer;3420 LegalizerHelper Helper(*MF, Info, Observer, B);3421 // Perform Legalization3422 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3423 Helper.lower(*UDivrem, 0, S64));3424 3425 const auto *CheckStr = R"(3426 CHECK: [[DIV:%[0-9]+]]:_(s64) = G_UDIV %0:_, %1:_3427 CHECK: [[REM:%[0-9]+]]:_(s64) = G_UREM %0:_, %1:_3428 )";3429 3430 // Check3431 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3432}3433 3434// Test G_SELECT lowering.3435// Note: This is for testing the legalizer, aarch64 does not lower scalar3436// selects like this.3437TEST_F(AArch64GISelMITest, LowerSelect) {3438 setUp();3439 if (!TM)3440 GTEST_SKIP();3441 3442 // Declare your legalization info3443 DefineLegalizerInfo(A, { getActionDefinitionsBuilder(G_SELECT).lower(); });3444 3445 LLT S1 = LLT::scalar(1);3446 LLT S32 = LLT::scalar(32);3447 auto Tst = B.buildTrunc(S1, Copies[0]);3448 auto SrcA = B.buildTrunc(S32, Copies[1]);3449 auto SrcB = B.buildTrunc(S32, Copies[2]);3450 auto SELECT = B.buildInstr(TargetOpcode::G_SELECT, {S32}, {Tst, SrcA, SrcB});3451 3452 AInfo Info(MF->getSubtarget());3453 DummyGISelObserver Observer;3454 LegalizerHelper Helper(*MF, Info, Observer, B);3455 // Perform Legalization3456 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3457 Helper.lower(*SELECT, 0, S32));3458 3459 auto CheckStr = R"(3460 CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC3461 CHECK: [[TRUE:%[0-9]+]]:_(s32) = G_TRUNC3462 CHECK: [[FALSE:%[0-9]+]]:_(s32) = G_TRUNC3463 CHECK: [[MSK:%[0-9]+]]:_(s32) = G_SEXT [[TST]]3464 CHECK: [[M:%[0-9]+]]:_(s32) = G_CONSTANT i32 -13465 CHECK: [[NEGMSK:%[0-9]+]]:_(s32) = G_XOR [[MSK]]:_, [[M]]:_3466 CHECK: [[TVAL:%[0-9]+]]:_(s32) = G_AND [[TRUE]]:_, [[MSK]]:_3467 CHECK: [[FVAL:%[0-9]+]]:_(s32) = G_AND [[FALSE]]:_, [[NEGMSK]]:_3468 CHECK: [[RES:%[0-9]+]]:_(s32) = G_OR [[TVAL]]:_, [[FVAL]]:_3469 )";3470 3471 // Check3472 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3473}3474 3475// Test widening of G_UNMERGE_VALUES3476TEST_F(AArch64GISelMITest, WidenUnmerge) {3477 setUp();3478 if (!TM)3479 GTEST_SKIP();3480 3481 DefineLegalizerInfo(A, {});3482 3483 // Check that widening G_UNMERGE_VALUES to a larger type than the source type3484 // works as expected3485 LLT P0{LLT::pointer(0, 64)};3486 LLT S32{LLT::scalar(32)};3487 LLT S96{LLT::scalar(96)};3488 3489 auto IntToPtr = B.buildIntToPtr(P0, Copies[0]);3490 auto UnmergePtr = B.buildUnmerge(S32, IntToPtr);3491 auto UnmergeScalar = B.buildUnmerge(S32, Copies[0]);3492 3493 AInfo Info(MF->getSubtarget());3494 DummyGISelObserver Observer;3495 LegalizerHelper Helper(*MF, Info, Observer, B);3496 3497 // Perform Legalization3498 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3499 Helper.widenScalar(*UnmergePtr, 0, S96));3500 3501 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3502 Helper.widenScalar(*UnmergeScalar, 0, S96));3503 3504 const auto *CheckStr = R"(3505 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3506 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY]]3507 CHECK: [[INT:%[0-9]+]]:_(s64) = G_PTRTOINT [[PTR]]3508 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[INT]]3509 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]3510 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 323511 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]3512 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]3513 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY]]3514 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[ANYEXT]]3515 CHECK: [[C:%[0-9]+]]:_(s96) = G_CONSTANT i96 323516 CHECK: [[LSHR:%[0-9]+]]:_(s96) = G_LSHR [[ANYEXT]]:_, [[C]]3517 CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[LSHR]]3518 )";3519 3520 // Check3521 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3522}3523 3524TEST_F(AArch64GISelMITest, BitcastLoad) {3525 setUp();3526 if (!TM)3527 GTEST_SKIP();3528 3529 LLT P0 = LLT::pointer(0, 64);3530 LLT S32 = LLT::scalar(32);3531 LLT V4S8 = LLT::fixed_vector(4, 8);3532 auto Ptr = B.buildUndef(P0);3533 3534 DefineLegalizerInfo(A, {});3535 3536 MachineMemOperand *MMO = B.getMF().getMachineMemOperand(3537 MachinePointerInfo(), MachineMemOperand::MOLoad, 4, Align(4));3538 auto Load = B.buildLoad(V4S8, Ptr, *MMO);3539 3540 AInfo Info(MF->getSubtarget());3541 DummyGISelObserver Observer;3542 B.setInsertPt(*EntryMBB, Load->getIterator());3543 LegalizerHelper Helper(*MF, Info, Observer, B);3544 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3545 Helper.bitcast(*Load, 0, S32));3546 3547 auto CheckStr = R"(3548 CHECK: [[PTR:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF3549 CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD3550 CHECK: [[CAST:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[LOAD]]3551 3552 )";3553 3554 // Check3555 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3556}3557 3558TEST_F(AArch64GISelMITest, BitcastStore) {3559 setUp();3560 if (!TM)3561 GTEST_SKIP();3562 3563 LLT P0 = LLT::pointer(0, 64);3564 LLT S32 = LLT::scalar(32);3565 LLT V4S8 = LLT::fixed_vector(4, 8);3566 auto Ptr = B.buildUndef(P0);3567 3568 DefineLegalizerInfo(A, {});3569 3570 MachineMemOperand *MMO = B.getMF().getMachineMemOperand(3571 MachinePointerInfo(), MachineMemOperand::MOStore, 4, Align(4));3572 auto Val = B.buildUndef(V4S8);3573 auto Store = B.buildStore(Val, Ptr, *MMO);3574 3575 AInfo Info(MF->getSubtarget());3576 DummyGISelObserver Observer;3577 LegalizerHelper Helper(*MF, Info, Observer, B);3578 B.setInsertPt(*EntryMBB, Store->getIterator());3579 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3580 Helper.bitcast(*Store, 0, S32));3581 3582 auto CheckStr = R"(3583 CHECK: [[VAL:%[0-9]+]]:_(<4 x s8>) = G_IMPLICIT_DEF3584 CHECK: [[CAST:%[0-9]+]]:_(s32) = G_BITCAST [[VAL]]3585 CHECK: G_STORE [[CAST]]3586 )";3587 3588 // Check3589 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3590}3591 3592TEST_F(AArch64GISelMITest, BitcastSelect) {3593 setUp();3594 if (!TM)3595 GTEST_SKIP();3596 3597 LLT S1 = LLT::scalar(1);3598 LLT S32 = LLT::scalar(32);3599 LLT V4S8 = LLT::fixed_vector(4, 8);3600 3601 DefineLegalizerInfo(A, {});3602 3603 auto Cond = B.buildUndef(S1);3604 auto Val0 = B.buildConstant(V4S8, 123);3605 auto Val1 = B.buildConstant(V4S8, 99);3606 3607 auto Select = B.buildSelect(V4S8, Cond, Val0, Val1);3608 3609 AInfo Info(MF->getSubtarget());3610 DummyGISelObserver Observer;3611 LegalizerHelper Helper(*MF, Info, Observer, B);3612 B.setInsertPt(*EntryMBB, Select->getIterator());3613 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3614 Helper.bitcast(*Select, 0, S32));3615 3616 auto CheckStr = R"(3617 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR3618 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR3619 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]3620 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]3621 CHECK: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT %{{[0-9]+}}:_(s1), [[CAST0]]:_, [[CAST1]]:_3622 CHECK: [[CAST2:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[SELECT]]3623 )";3624 3625 // Check3626 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3627 3628 // Doesn't make sense3629 auto VCond = B.buildUndef(LLT::fixed_vector(4, 1));3630 auto VSelect = B.buildSelect(V4S8, VCond, Val0, Val1);3631 3632 B.setInsertPt(*EntryMBB, VSelect->getIterator());3633 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,3634 Helper.bitcast(*VSelect, 0, S32));3635 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,3636 Helper.bitcast(*VSelect, 1, LLT::scalar(4)));3637}3638 3639TEST_F(AArch64GISelMITest, BitcastBitOps) {3640 setUp();3641 if (!TM)3642 GTEST_SKIP();3643 3644 LLT S32 = LLT::scalar(32);3645 LLT V4S8 = LLT::fixed_vector(4, 8);3646 3647 DefineLegalizerInfo(A, {});3648 3649 auto Val0 = B.buildConstant(V4S8, 123);3650 auto Val1 = B.buildConstant(V4S8, 99);3651 auto And = B.buildAnd(V4S8, Val0, Val1);3652 auto Or = B.buildOr(V4S8, Val0, Val1);3653 auto Xor = B.buildXor(V4S8, Val0, Val1);3654 3655 AInfo Info(MF->getSubtarget());3656 DummyGISelObserver Observer;3657 LegalizerHelper Helper(*MF, Info, Observer, B);3658 B.setInsertPt(*EntryMBB, And->getIterator());3659 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3660 Helper.bitcast(*And, 0, S32));3661 3662 B.setInsertPt(*EntryMBB, Or->getIterator());3663 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3664 Helper.bitcast(*Or, 0, S32));3665 3666 B.setInsertPt(*EntryMBB, Xor->getIterator());3667 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3668 Helper.bitcast(*Xor, 0, S32));3669 3670 auto CheckStr = R"(3671 CHECK: [[VAL0:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR3672 CHECK: [[VAL1:%[0-9]+]]:_(<4 x s8>) = G_BUILD_VECTOR3673 CHECK: [[CAST0:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]3674 CHECK: [[CAST1:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]3675 CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[CAST0]]:_, [[CAST1]]:_3676 CHECK: [[CAST_AND:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[AND]]3677 CHECK: [[CAST2:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]3678 CHECK: [[CAST3:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]3679 CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[CAST2]]:_, [[CAST3]]:_3680 CHECK: [[CAST_OR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[OR]]3681 CHECK: [[CAST4:%[0-9]+]]:_(s32) = G_BITCAST [[VAL0]]3682 CHECK: [[CAST5:%[0-9]+]]:_(s32) = G_BITCAST [[VAL1]]3683 CHECK: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[CAST4]]:_, [[CAST5]]:_3684 CHECK: [[CAST_XOR:%[0-9]+]]:_(<4 x s8>) = G_BITCAST [[XOR]]3685 )";3686 3687 // Check3688 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3689}3690 3691TEST_F(AArch64GISelMITest, CreateLibcall) {3692 setUp();3693 if (!TM)3694 GTEST_SKIP();3695 3696 DefineLegalizerInfo(A, {});3697 3698 AInfo Info(MF->getSubtarget());3699 DummyGISelObserver Observer;3700 LostDebugLocObserver DummyLocObserver("");3701 3702 LLVMContext &Ctx = MF->getFunction().getContext();3703 auto *RetTy = Type::getVoidTy(Ctx);3704 3705 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3706 createLibcall(B, "abort", {{}, RetTy, 0}, {}, CallingConv::C,3707 DummyLocObserver, nullptr));3708 3709 auto CheckStr = R"(3710 CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp3711 CHECK: BL &abort3712 CHECK: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp3713 )";3714 3715 // Check3716 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3717}3718 3719// Test narrowing of G_IMPLICIT_DEF3720TEST_F(AArch64GISelMITest, NarrowImplicitDef) {3721 setUp();3722 if (!TM)3723 GTEST_SKIP();3724 3725 DefineLegalizerInfo(A, {});3726 3727 // Make sure that G_IMPLICIT_DEF can be narrowed if the original size is not a3728 // multiple of narrow size3729 LLT S32{LLT::scalar(32)};3730 LLT S48{LLT::scalar(48)};3731 LLT S64{LLT::scalar(64)};3732 LLT V2S64{{LLT::fixed_vector(2, 64)}};3733 3734 auto Implicit1 = B.buildUndef(S64);3735 auto Implicit2 = B.buildUndef(S64);3736 auto Implicit3 = B.buildUndef(V2S64);3737 auto Implicit4 = B.buildUndef(V2S64);3738 3739 AInfo Info(MF->getSubtarget());3740 DummyGISelObserver Observer;3741 LegalizerHelper Helper(*MF, Info, Observer, B);3742 3743 // Perform Legalization3744 3745 B.setInsertPt(*EntryMBB, Implicit1->getIterator());3746 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3747 Helper.narrowScalar(*Implicit1, 0, S48));3748 3749 B.setInsertPt(*EntryMBB, Implicit2->getIterator());3750 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3751 Helper.narrowScalar(*Implicit2, 0, S32));3752 3753 B.setInsertPt(*EntryMBB, Implicit3->getIterator());3754 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3755 Helper.narrowScalar(*Implicit3, 0, S48));3756 3757 B.setInsertPt(*EntryMBB, Implicit4->getIterator());3758 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3759 Helper.narrowScalar(*Implicit4, 0, S32));3760 3761 const auto *CheckStr = R"(3762 CHECK: [[DEF:%[0-9]+]]:_(s48) = G_IMPLICIT_DEF3763 CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[DEF]]3764 3765 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3766 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3767 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[DEF]]:_(s32), [[DEF1]]3768 3769 CHECK: [[DEF:%[0-9]+]]:_(<2 x s48>) = G_IMPLICIT_DEF3770 CHECK: [[ANYEXT:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[DEF]]3771 3772 CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3773 CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3774 CHECK: [[DEF2:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3775 CHECK: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3776 CHECK: [[BV:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[DEF]]:_(s32), [[DEF1]]:_(s32), [[DEF2]]:_(s32), [[DEF3]]:_(s32)3777 )";3778 3779 // Check3780 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3781}3782 3783// Test widening of G_FREEZE3784TEST_F(AArch64GISelMITest, WidenFreeze) {3785 setUp();3786 if (!TM)3787 GTEST_SKIP();3788 3789 DefineLegalizerInfo(A, {});3790 3791 // Make sure that G_FREEZE is widened with anyext3792 LLT S64{LLT::scalar(64)};3793 LLT S128{LLT::scalar(128)};3794 LLT V2S32{LLT::fixed_vector(2, 32)};3795 LLT V2S64{LLT::fixed_vector(2, 64)};3796 3797 auto Vector = B.buildBitcast(V2S32, Copies[0]);3798 3799 auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});3800 auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector});3801 3802 AInfo Info(MF->getSubtarget());3803 DummyGISelObserver Observer;3804 LegalizerHelper Helper(*MF, Info, Observer, B);3805 3806 // Perform Legalization3807 3808 B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());3809 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3810 Helper.widenScalar(*FreezeScalar, 0, S128));3811 3812 B.setInsertPt(*EntryMBB, FreezeVector->getIterator());3813 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3814 Helper.widenScalar(*FreezeVector, 0, V2S64));3815 3816 const auto *CheckStr = R"(3817 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3818 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]3819 3820 CHECK: [[ANYEXT:%[0-9]+]]:_(s128) = G_ANYEXT [[COPY]]3821 CHECK: [[FREEZE:%[0-9]+]]:_(s128) = G_FREEZE [[ANYEXT]]3822 CHECK: [[TRUNC:%[0-9]+]]:_(s64) = G_TRUNC [[FREEZE]]3823 3824 CHECK: [[ANYEXT1:%[0-9]+]]:_(<2 x s64>) = G_ANYEXT [[BITCAST]]3825 CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[ANYEXT1]]3826 CHECK: [[TRUNC1:%[0-9]+]]:_(<2 x s32>) = G_TRUNC [[FREEZE1]]3827 )";3828 3829 // Check3830 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3831}3832 3833// Test narrowing of G_FREEZE3834TEST_F(AArch64GISelMITest, NarrowFreeze) {3835 setUp();3836 if (!TM)3837 GTEST_SKIP();3838 3839 DefineLegalizerInfo(A, {});3840 3841 // Make sure that G_FREEZE is narrowed using unmerge/extract3842 LLT S32{LLT::scalar(32)};3843 LLT S33{LLT::scalar(33)};3844 LLT S48{LLT::scalar(48)};3845 LLT S64{LLT::scalar(64)};3846 LLT V2S16{LLT::fixed_vector(2, 16)};3847 LLT V3S16{LLT::fixed_vector(3, 16)};3848 LLT V4S16{LLT::fixed_vector(4, 16)};3849 3850 auto Trunc = B.buildTrunc(S33, {Copies[0]});3851 auto Trunc1 = B.buildTrunc(S48, {Copies[0]});3852 auto Vector = B.buildBitcast(V3S16, Trunc1);3853 3854 auto FreezeScalar = B.buildInstr(TargetOpcode::G_FREEZE, {S64}, {Copies[0]});3855 auto FreezeOdd = B.buildInstr(TargetOpcode::G_FREEZE, {S33}, {Trunc});3856 auto FreezeVector = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});3857 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V3S16}, {Vector});3858 3859 AInfo Info(MF->getSubtarget());3860 DummyGISelObserver Observer;3861 LegalizerHelper Helper(*MF, Info, Observer, B);3862 3863 // Perform Legalization3864 3865 B.setInsertPt(*EntryMBB, FreezeScalar->getIterator());3866 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3867 Helper.narrowScalar(*FreezeScalar, 0, S32));3868 3869 // This should be followed by narrowScalar to S32.3870 B.setInsertPt(*EntryMBB, FreezeOdd->getIterator());3871 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3872 Helper.widenScalar(*FreezeOdd, 0, S64));3873 3874 B.setInsertPt(*EntryMBB, FreezeVector->getIterator());3875 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3876 Helper.fewerElementsVector(*FreezeVector, 0, V2S16));3877 3878 // This should be followed by fewerElements to V2S16.3879 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());3880 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3881 Helper.moreElementsVector(*FreezeVector1, 0, V4S16));3882 3883 const auto *CheckStr = R"(3884 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3885 CHECK: [[TRUNC:%[0-9]+]]:_(s33) = G_TRUNC [[COPY]]3886 CHECK: [[TRUNC1:%[0-9]+]]:_(s48) = G_TRUNC [[COPY]]3887 CHECK: [[BITCAST:%[0-9]+]]:_(<3 x s16>) = G_BITCAST [[TRUNC1]]3888 3889 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]]3890 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]3891 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]3892 CHECK: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[FREEZE]]:_(s32), [[FREEZE1]]3893 3894 CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[TRUNC]]3895 CHECK: [[FREEZE2:%[0-9]+]]:_(s64) = G_FREEZE [[ANYEXT]]3896 CHECK: [[TRUNC1:%[0-9]+]]:_(s33) = G_TRUNC [[FREEZE2]]3897 3898 CHECK: [[UV2:%[0-9]+]]:_(s16), [[UV3:%[0-9]+]]:_(s16), [[UV4:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]3899 CHECK: [[BV:%[0-9]+]]:_(<2 x s16>) = G_BUILD_VECTOR [[UV2]]:_(s16), [[UV3]]:_(s16)3900 CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[BV]]3901 CHECK: [[FREEZE4:%[0-9]+]]:_(s16) = G_FREEZE [[UV4]]3902 CHECK: [[FREEZE3_E0:%[0-9]+]]:_(s16), [[FREEZE3_E1:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE3]]3903 CHECK: [[BV1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE3_E0]]:_(s16), [[FREEZE3_E1]]:_(s16), [[FREEZE4]]:_(s16)3904 3905 CHECK: [[UV5:%[0-9]+]]:_(s16), [[UV6:%[0-9]+]]:_(s16), [[UV7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[BITCAST]]3906 CHECK: [[IMP_DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF3907 CHECK: [[BV1:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UV5]]:_(s16), [[UV6]]:_(s16), [[UV7]]:_(s16), [[IMP_DEF]]:_(s16)3908 CHECK: [[FREEZE5:%[0-9]+]]:_(<4 x s16>) = G_FREEZE [[BV1]]3909 CHECK: [[FREEZE5_E0:%[0-9]+]]:_(s16), [[FREEZE5_E1:%[0-9]+]]:_(s16), [[FREEZE5_E2:%[0-9]+]]:_(s16), [[FREEZE5_E3:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[FREEZE5]]3910 CHECK: [[BV2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[FREEZE5_E0]]:_(s16), [[FREEZE5_E1]]:_(s16), [[FREEZE5_E2]]:_(s16)3911 )";3912 3913 // Check3914 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3915}3916 3917// Test fewer elements of G_FREEZE3918TEST_F(AArch64GISelMITest, FewerElementsFreeze) {3919 setUp();3920 if (!TM)3921 GTEST_SKIP();3922 3923 DefineLegalizerInfo(A, {});3924 3925 LLT S32{LLT::scalar(32)};3926 LLT V2S16{LLT::fixed_vector(2, 16)};3927 LLT V2S32{LLT::fixed_vector(2, 32)};3928 LLT V4S16{LLT::fixed_vector(4, 16)};3929 3930 auto Vector1 = B.buildBitcast(V2S32, Copies[0]);3931 auto Vector2 = B.buildBitcast(V4S16, Copies[0]);3932 3933 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});3934 auto FreezeVector2 = B.buildInstr(TargetOpcode::G_FREEZE, {V4S16}, {Vector2});3935 3936 AInfo Info(MF->getSubtarget());3937 DummyGISelObserver Observer;3938 LegalizerHelper Helper(*MF, Info, Observer, B);3939 3940 // Perform Legalization3941 3942 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());3943 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3944 Helper.fewerElementsVector(*FreezeVector1, 0, S32));3945 3946 B.setInsertPt(*EntryMBB, FreezeVector2->getIterator());3947 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3948 Helper.fewerElementsVector(*FreezeVector2, 0, V2S16));3949 3950 const auto *CheckStr = R"(3951 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3952 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]3953 CHECK: [[BITCAST1:%[0-9]+]]:_(<4 x s16>) = G_BITCAST [[COPY]]3954 3955 CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]3956 CHECK: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[UV]]3957 CHECK: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[UV1]]3958 CHECK: [[MV:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FREEZE]]:_(s32), [[FREEZE1]]3959 3960 CHECK: [[UV:%[0-9]+]]:_(<2 x s16>), [[UV1:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[BITCAST1]]3961 CHECK: [[FREEZE2:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV]]3962 CHECK: [[FREEZE3:%[0-9]+]]:_(<2 x s16>) = G_FREEZE [[UV1]]3963 CHECK: [[MV:%[0-9]+]]:_(<4 x s16>) = G_CONCAT_VECTORS [[FREEZE2]]:_(<2 x s16>), [[FREEZE3]]3964 )";3965 3966 // Check3967 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;3968}3969 3970// Test more elements of G_FREEZE3971TEST_F(AArch64GISelMITest, MoreElementsFreeze) {3972 setUp();3973 if (!TM)3974 GTEST_SKIP();3975 3976 DefineLegalizerInfo(A, {});3977 3978 LLT V2S32{LLT::fixed_vector(2, 32)};3979 LLT V4S32{LLT::fixed_vector(4, 32)};3980 3981 auto Vector1 = B.buildBitcast(V2S32, Copies[0]);3982 auto FreezeVector1 = B.buildInstr(TargetOpcode::G_FREEZE, {V2S32}, {Vector1});3983 3984 AInfo Info(MF->getSubtarget());3985 DummyGISelObserver Observer;3986 LegalizerHelper Helper(*MF, Info, Observer, B);3987 3988 // Perform Legalization3989 B.setInsertPt(*EntryMBB, FreezeVector1->getIterator());3990 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,3991 Helper.moreElementsVector(*FreezeVector1, 0, V4S32));3992 3993 const auto *CheckStr = R"(3994 CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY3995 CHECK: [[BITCAST:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[COPY]]3996 CHECK: [[BITCAST_E0:%[0-9]+]]:_(s32), [[BITCAST_E1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[BITCAST]]:_(<2 x s32>)3997 CHECK: [[IMP_DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF3998 CHECK: [[BITCAST_LARGE:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[BITCAST_E0]]:_(s32), [[BITCAST_E1]]:_(s32), [[IMP_DEF]]:_(s32), [[IMP_DEF]]:_(s32)3999 CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BITCAST_LARGE]]4000 CHECK: [[FREEZE_E0:%[0-9]+]]:_(s32), [[FREEZE_E1:%[0-9]+]]:_(s32), [[FREEZE_E2:%[0-9]+]]:_(s32), [[FREEZE_E3:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[FREEZE]]:_(<4 x s32>)4001 CHECK: (<2 x s32>) = G_BUILD_VECTOR [[FREEZE_E0]]:_(s32), [[FREEZE_E1]]:_(s32)4002 )";4003 4004 // Check4005 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4006}4007 4008// Test fewer elements of G_INSERT_VECTOR_ELEMENT4009TEST_F(AArch64GISelMITest, FewerElementsInsertVectorElt) {4010 setUp();4011 if (!TM)4012 GTEST_SKIP();4013 4014 DefineLegalizerInfo(A, {});4015 4016 LLT P0{LLT::pointer(0, 64)};4017 LLT S64{LLT::scalar(64)};4018 LLT S16{LLT::scalar(16)};4019 LLT V2S16{LLT::fixed_vector(2, 16)};4020 LLT V3S16{LLT::fixed_vector(3, 16)};4021 LLT V8S16{LLT::fixed_vector(8, 16)};4022 4023 auto Ptr0 = B.buildIntToPtr(P0, Copies[0]);4024 auto VectorV8 = B.buildLoad(V8S16, Ptr0, MachinePointerInfo(), Align(8));4025 auto Value = B.buildTrunc(S16, Copies[1]);4026 4027 auto Seven = B.buildConstant(S64, 7);4028 auto InsertV8Constant7_0 =4029 B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);4030 auto InsertV8Constant7_1 =4031 B.buildInsertVectorElement(V8S16, VectorV8, Value, Seven);4032 4033 B.buildStore(InsertV8Constant7_0, Ptr0, MachinePointerInfo(), Align(8),4034 MachineMemOperand::MOVolatile);4035 B.buildStore(InsertV8Constant7_1, Ptr0, MachinePointerInfo(), Align(8),4036 MachineMemOperand::MOVolatile);4037 4038 AInfo Info(MF->getSubtarget());4039 DummyGISelObserver Observer;4040 LegalizerHelper Helper(*MF, Info, Observer, B);4041 4042 // Perform Legalization4043 B.setInsertPt(*EntryMBB, InsertV8Constant7_0->getIterator());4044 4045 // This should index the high element of the 4th piece of an unmerge.4046 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4047 Helper.fewerElementsVector(*InsertV8Constant7_0, 0, V2S16));4048 4049 // This case requires extracting an intermediate vector type into the target4050 // v4s16.4051 B.setInsertPt(*EntryMBB, InsertV8Constant7_1->getIterator());4052 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4053 Helper.fewerElementsVector(*InsertV8Constant7_1, 0, V3S16));4054 4055 const auto *CheckStr = R"(4056 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY4057 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY4058 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY4059 CHECK: [[PTR0:%[0-9]+]]:_(p0) = G_INTTOPTR [[COPY0]]4060 CHECK: [[VEC8:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[PTR0]]:_(p0) :: (load (<8 x s16>), align 8)4061 CHECK: [[INSERT_VAL:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]]4062 4063 4064 CHECK: [[UNMERGE0:%[0-9]+]]:_(<2 x s16>), [[UNMERGE1:%[0-9]+]]:_(<2 x s16>), [[UNMERGE2:%[0-9]+]]:_(<2 x s16>), [[UNMERGE3:%[0-9]+]]:_(<2 x s16>) = G_UNMERGE_VALUES [[VEC8]]4065 CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 14066 CHECK: [[SUB_INSERT_7:%[0-9]+]]:_(<2 x s16>) = G_INSERT_VECTOR_ELT [[UNMERGE3]]:_, [[INSERT_VAL]]:_(s16), [[ONE]]4067 CHECK: [[INSERT_V8_7_0:%[0-9]+]]:_(<8 x s16>) = G_CONCAT_VECTORS [[UNMERGE0]]:_(<2 x s16>), [[UNMERGE1]]:_(<2 x s16>), [[UNMERGE2]]:_(<2 x s16>), [[SUB_INSERT_7]]:_(<2 x s16>)4068 4069 4070 CHECK: [[UNMERGE1_0:%[0-9]+]]:_(s16), [[UNMERGE1_1:%[0-9]+]]:_(s16), [[UNMERGE1_2:%[0-9]+]]:_(s16), [[UNMERGE1_3:%[0-9]+]]:_(s16), [[UNMERGE1_4:%[0-9]+]]:_(s16), [[UNMERGE1_5:%[0-9]+]]:_(s16), [[UNMERGE1_6:%[0-9]+]]:_(s16), [[UNMERGE1_7:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[VEC8]]:_(<8 x s16>)4071 CHECK: [[IMPDEF_S16:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF4072 CHECK: [[BUILD0:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_0]]:_(s16), [[UNMERGE1_1]]:_(s16), [[UNMERGE1_2]]:_(s16)4073 CHECK: [[BUILD1:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_3]]:_(s16), [[UNMERGE1_4]]:_(s16), [[UNMERGE1_5]]:_(s16)4074 CHECK: [[BUILD2:%[0-9]+]]:_(<3 x s16>) = G_BUILD_VECTOR [[UNMERGE1_6]]:_(s16), [[UNMERGE1_7]]:_(s16), [[IMPDEF_S16]]:_(s16)4075 CHECK: [[IMPDEF_V3S16:%[0-9]+]]:_(<3 x s16>) = G_IMPLICIT_DEF4076 CHECK: [[ONE_1:%[0-9]+]]:_(s64) = G_CONSTANT i64 14077 CHECK: [[SUB_INSERT_7_V3S16:%[0-9]+]]:_(<3 x s16>) = G_INSERT_VECTOR_ELT [[BUILD2]]:_, [[INSERT_VAL]]:_(s16), [[ONE_1]]4078 4079 CHECK: [[WIDE_CONCAT_DEAD:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)4080 CHECK: [[WIDE_CONCAT:%[0-9]+]]:_(<24 x s16>) = G_CONCAT_VECTORS [[BUILD0]]:_(<3 x s16>), [[BUILD1]]:_(<3 x s16>), [[SUB_INSERT_7_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>), [[IMPDEF_V3S16]]:_(<3 x s16>)4081 CHECK: [[INSERT_V8_7_1:%[0-9]+]]:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>), %{{[0-9]+}}:_(<8 x s16>) = G_UNMERGE_VALUES [[WIDE_CONCAT]]:_(<24 x s16>)4082 4083 4084 CHECK: G_STORE [[INSERT_V8_7_0]]4085 CHECK: G_STORE [[INSERT_V8_7_1]]4086 )";4087 4088 // Check4089 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4090}4091 4092// Test widen scalar of G_UNMERGE_VALUES4093TEST_F(AArch64GISelMITest, widenScalarUnmerge) {4094 setUp();4095 if (!TM)4096 GTEST_SKIP();4097 4098 DefineLegalizerInfo(A, {});4099 4100 LLT S96{LLT::scalar(96)};4101 LLT S64{LLT::scalar(64)};4102 LLT S48{LLT::scalar(48)};4103 4104 auto Src = B.buildAnyExt(S96, Copies[0]);4105 auto Unmerge = B.buildUnmerge(S48, Src);4106 4107 AInfo Info(MF->getSubtarget());4108 DummyGISelObserver Observer;4109 LegalizerHelper Helper(*MF, Info, Observer, B);4110 4111 // Perform Legalization4112 B.setInsertPt(*EntryMBB, Unmerge->getIterator());4113 4114 // This should create unmerges to a GCD type (S16), then remerge to S484115 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4116 Helper.widenScalar(*Unmerge, 0, S64));4117 4118 const auto *CheckStr = R"(4119 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY4120 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY4121 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY4122 CHECK: [[ANYEXT:%[0-9]+]]:_(s96) = G_ANYEXT [[COPY0]]4123 CHECK: [[ANYEXT1:%[0-9]+]]:_(s192) = G_ANYEXT [[ANYEXT]]4124 CHECK: [[UNMERGE:%[0-9]+]]:_(s64), [[UNMERGE1:%[0-9]+]]:_(s64), [[UNMERGE2:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[ANYEXT1]]4125 CHECK: [[UNMERGE3:%[0-9]+]]:_(s16), [[UNMERGE4:%[0-9]+]]:_(s16), [[UNMERGE5:%[0-9]+]]:_(s16), [[UNMERGE6:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE]]4126 CHECK: [[UNMERGE7:%[0-9]+]]:_(s16), [[UNMERGE8:%[0-9]+]]:_(s16), [[UNMERGE9:%[0-9]+]]:_(s16), [[UNMERGE10:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE1]]4127 CHECK: [[UNMERGE11:%[0-9]+]]:_(s16), [[UNMERGE12:%[0-9]+]]:_(s16), [[UNMERGE13:%[0-9]+]]:_(s16), [[UNMERGE14:%[0-9]+]]:_(s16) = G_UNMERGE_VALUES [[UNMERGE2]]4128 CHECK: [[MERGE:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE3]]:_(s16), [[UNMERGE4]]:_(s16), [[UNMERGE5]]:_(s16)4129 CHECK: [[MERGE1:%[0-9]+]]:_(s48) = G_MERGE_VALUES [[UNMERGE6]]:_(s16), [[UNMERGE7]]:_(s16), [[UNMERGE8]]:_(s16)4130 )";4131 4132 // Check4133 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4134}4135 4136// Test moreElements of G_SHUFFLE_VECTOR.4137TEST_F(AArch64GISelMITest, moreElementsShuffle) {4138 setUp();4139 if (!TM)4140 GTEST_SKIP();4141 4142 DefineLegalizerInfo(A, {});4143 4144 LLT S64{LLT::scalar(64)};4145 LLT V6S64 = LLT::fixed_vector(6, S64);4146 4147 auto V1 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],4148 Copies[1], Copies[0], Copies[1]});4149 auto V2 = B.buildBuildVector(V6S64, {Copies[0], Copies[1], Copies[0],4150 Copies[1], Copies[0], Copies[1]});4151 auto Shuffle = B.buildShuffleVector(V6S64, V1, V2, {3, 4, 7, 0, 1, 11});4152 4153 AInfo Info(MF->getSubtarget());4154 DummyGISelObserver Observer;4155 LegalizerHelper Helper(*MF, Info, Observer, B);4156 4157 // Perform Legalization4158 B.setInsertPt(*EntryMBB, Shuffle->getIterator());4159 4160 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4161 Helper.moreElementsVector(*Shuffle, 0, LLT::fixed_vector(8, S64)));4162 4163 const auto *CheckStr = R"(4164 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY4165 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY4166 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY4167 CHECK: [[BV1:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR4168 CHECK: [[BV2:%[0-9]+]]:_(<6 x s64>) = G_BUILD_VECTOR4169 4170 CHECK: [[BV1_E0:%[0-9]+]]:_(s64), [[BV1_E1:%[0-9]+]]:_(s64), [[BV1_E2:%[0-9]+]]:_(s64), [[BV1_E3:%[0-9]+]]:_(s64), [[BV1_E4:%[0-9]+]]:_(s64), [[BV1_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV1]]:_(<6 x s64>)4171 CHECK: [[IMP_DEF0:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF4172 CHECK: [[BV1_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV1_E0]]:_(s64), [[BV1_E1]]:_(s64), [[BV1_E2]]:_(s64), [[BV1_E3]]:_(s64), [[BV1_E4]]:_(s64), [[BV1_E5]]:_(s64), [[IMP_DEF0]]:_(s64), [[IMP_DEF0]]:_(s64)4173 4174 CHECK: [[BV2_E0:%[0-9]+]]:_(s64), [[BV2_E1:%[0-9]+]]:_(s64), [[BV2_E2:%[0-9]+]]:_(s64), [[BV2_E3:%[0-9]+]]:_(s64), [[BV2_E4:%[0-9]+]]:_(s64), [[BV2_E5:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[BV2]]:_(<6 x s64>)4175 CHECK: [[IMP_DEF1:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF4176 CHECK: [[BV2_LARGE:%[0-9]+]]:_(<8 x s64>) = G_BUILD_VECTOR [[BV2_E0]]:_(s64), [[BV2_E1]]:_(s64), [[BV2_E2]]:_(s64), [[BV2_E3]]:_(s64), [[BV2_E4]]:_(s64), [[BV2_E5]]:_(s64), [[IMP_DEF1]]:_(s64), [[IMP_DEF1]]:_(s64)4177 4178 CHECK: [[SHUF:%[0-9]+]]:_(<8 x s64>) = G_SHUFFLE_VECTOR [[BV1_LARGE]]:_(<8 x s64>), [[BV2_LARGE]]:_, shufflemask(3, 4, 9, 0, 1, 13, undef, undef)4179 4180 CHECK: [[SHUF_E0:%[0-9]+]]:_(s64), [[SHUF_E1:%[0-9]+]]:_(s64), [[SHUF_E2:%[0-9]+]]:_(s64), [[SHUF_E3:%[0-9]+]]:_(s64), [[SHUF_E4:%[0-9]+]]:_(s64), [[SHUF_E5:%[0-9]+]]:_(s64), [[SHUF_E6:%[0-9]+]]:_(s64), [[SHUF_E7:%[0-9]+]]:_(s64) = G_UNMERGE_VALUES [[SHUF]]:_(<8 x s64>)4181 CHECK: (<6 x s64>) = G_BUILD_VECTOR [[SHUF_E0]]:_(s64), [[SHUF_E1]]:_(s64), [[SHUF_E2]]:_(s64), [[SHUF_E3]]:_(s64), [[SHUF_E4]]:_(s64), [[SHUF_E5]]:_(s64)4182 )";4183 4184 // Check4185 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4186}4187 4188// Test narror scalar of G_SHL with constant shift amount4189TEST_F(AArch64GISelMITest, narrowScalarShiftByConstant) {4190 setUp();4191 if (!TM)4192 GTEST_SKIP();4193 4194 DefineLegalizerInfo(A, {});4195 4196 LLT S64{LLT::scalar(64)};4197 LLT S32{LLT::scalar(32)};4198 4199 auto Constant = B.buildConstant(S64, 33);4200 auto Trunc = B.buildTrunc(S32, Constant);4201 auto Shift = B.buildShl(S64, Copies[0], Trunc);4202 4203 AInfo Info(MF->getSubtarget());4204 DummyGISelObserver Observer;4205 LegalizerHelper Helper(*MF, Info, Observer, B);4206 4207 // Perform Legalization4208 B.setInsertPt(*EntryMBB, Shift->getIterator());4209 4210 // This should detect the G_CONSTANT feeding the G_SHL through a G_TRUNC4211 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4212 Helper.narrowScalarShift(*Shift, 0, S32));4213 4214 const auto *CheckStr = R"(4215 CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY4216 CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY4217 CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY4218 CHECK: [[THIRTY3:%[0-9]+]]:_(s64) = G_CONSTANT i64 334219 CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC %4:_(s64)4220 CHECK: [[UNMERGE:%[0-9]+]]:_(s32), [[UNMERGE2:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY0]]4221 CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 04222 CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 14223 CHECK: [[SHIFT:%[0-9]+]]:_(s32) = G_SHL [[UNMERGE]]:_, [[ONE]]:_(s32)4224 CHECK: [[MERGE:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[ZERO]]:_(s32), [[SHIFT]]:_(s32)4225 )";4226 4227 // Check4228 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4229}4230 4231TEST_F(AArch64GISelMITest, MoreElementsSelect) {4232 setUp();4233 if (!TM)4234 GTEST_SKIP();4235 4236 LLT s1 = LLT::scalar(1);4237 LLT s64 = LLT::scalar(64);4238 LLT v2s1 = LLT::fixed_vector(2, 1);4239 LLT v2s32 = LLT::fixed_vector(2, 32);4240 4241 LegalizerInfo LI;4242 DummyGISelObserver Observer;4243 LegalizerHelper Helper(*MF, LI, Observer, B);4244 4245 B.setInsertPt(*EntryMBB, EntryMBB->end());4246 4247 auto Val0 = B.buildBitcast(v2s32, Copies[0]);4248 auto Val1 = B.buildBitcast(v2s32, Copies[1]);4249 4250 // Build select of vectors with scalar condition.4251 auto Zero = B.buildConstant(s64, 0);4252 auto Cond = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[2], Zero);4253 auto Select = B.buildSelect(v2s32, Cond, Val0, Val1);4254 4255 // Splat the condition into a vector select4256 B.setInstr(*Select);4257 4258 EXPECT_EQ(LegalizerHelper::LegalizeResult::UnableToLegalize,4259 Helper.moreElementsVector(*Select, 1, LLT::fixed_vector(3, 1)));4260 EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,4261 Helper.moreElementsVector(*Select, 1, v2s1));4262 4263 auto CheckStr = R"(4264 CHECK: [[BITCAST0:%[0-9]+]]:_(<2 x s32>) = G_BITCAST4265 CHECK: [[BITCAST1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST4266 CHECK: [[ZERO0:%[0-9]+]]:_(s64) = G_CONSTANT i64 04267 CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), %{{[0-9]+}}:_(s64), [[ZERO0]]4268 CHECK: [[IMPDEF:%[0-9]+]]:_(<2 x s1>) = G_IMPLICIT_DEF4269 CHECK: [[ZERO1:%[0-9]+]]:_(s64) = G_CONSTANT i64 04270 CHECK: [[INSERT:%[0-9]+]]:_(<2 x s1>) = G_INSERT_VECTOR_ELT [[IMPDEF]]:_, [[CMP]]:_(s1), [[ZERO1]]4271 CHECK: [[SHUFFLE:%[0-9]+]]:_(<2 x s1>) = G_SHUFFLE_VECTOR [[INSERT]]:_(<2 x s1>), [[IMPDEF]]:_, shufflemask(0, 0)4272 CHECK: [[SELECT:%[0-9]+]]:_(<2 x s32>) = G_SELECT [[SHUFFLE]]:_(<2 x s1>), [[BITCAST0]]:_, [[BITCAST1]]:_4273 )";4274 4275 EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;4276}4277 4278} // namespace4279