1 //===- KnownBitsTest.cpp -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "GISelMITest.h" 10 #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" 11 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 12 13 TEST_F(AArch64GISelMITest, TestKnownBitsCst) { 14 StringRef MIRString = " %3:_(s8) = G_CONSTANT i8 1\n" 15 " %4:_(s8) = COPY %3\n"; 16 setUp(MIRString); 17 if (!TM) 18 return; 19 unsigned CopyReg = Copies[Copies.size() - 1]; 20 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 21 unsigned SrcReg = FinalCopy->getOperand(1).getReg(); 22 unsigned DstReg = FinalCopy->getOperand(0).getReg(); 23 GISelKnownBits Info(*MF); 24 KnownBits Res = Info.getKnownBits(SrcReg); 25 EXPECT_EQ((uint64_t)1, Res.One.getZExtValue()); 26 EXPECT_EQ((uint64_t)0xfe, Res.Zero.getZExtValue()); 27 28 KnownBits Res2 = Info.getKnownBits(DstReg); 29 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 30 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 31 } 32 33 TEST_F(AArch64GISelMITest, TestKnownBitsCstWithClass) { 34 StringRef MIRString = " %10:gpr32 = MOVi32imm 1\n" 35 " %4:_(s32) = COPY %10\n"; 36 setUp(MIRString); 37 if (!TM) 38 return; 39 unsigned CopyReg = Copies[Copies.size() - 1]; 40 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 41 unsigned SrcReg = FinalCopy->getOperand(1).getReg(); 42 unsigned DstReg = FinalCopy->getOperand(0).getReg(); 43 GISelKnownBits Info(*MF); 44 KnownBits Res = Info.getKnownBits(SrcReg); 45 // We can't analyze %3 due to the register class constraint. We will get a 46 // default-constructed KnownBits back. 47 EXPECT_EQ((uint64_t)1, Res.getBitWidth()); 48 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 49 EXPECT_EQ((uint64_t)0, Res.Zero.getZExtValue()); 50 51 KnownBits Res2 = Info.getKnownBits(DstReg); 52 // We still don't know the values due to the register class constraint but %4 53 // did reveal the size of %3. 54 EXPECT_EQ((uint64_t)32, Res2.getBitWidth()); 55 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 56 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 57 } 58 59 // Check that we are able to track bits through PHIs 60 // and get the intersections of everything we know on each operand. 61 TEST_F(AArch64GISelMITest, TestKnownBitsCstPHI) { 62 StringRef MIRString = " bb.10:\n" 63 " %10:_(s8) = G_CONSTANT i8 3\n" 64 " %11:_(s1) = G_IMPLICIT_DEF\n" 65 " G_BRCOND %11(s1), %bb.11\n" 66 " G_BR %bb.12\n" 67 "\n" 68 " bb.11:\n" 69 " %12:_(s8) = G_CONSTANT i8 2\n" 70 " G_BR %bb.12\n" 71 "\n" 72 " bb.12:\n" 73 " %13:_(s8) = PHI %10(s8), %bb.10, %12(s8), %bb.11\n" 74 " %14:_(s8) = COPY %13\n"; 75 setUp(MIRString); 76 if (!TM) 77 return; 78 Register CopyReg = Copies[Copies.size() - 1]; 79 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 80 Register SrcReg = FinalCopy->getOperand(1).getReg(); 81 Register DstReg = FinalCopy->getOperand(0).getReg(); 82 GISelKnownBits Info(*MF); 83 KnownBits Res = Info.getKnownBits(SrcReg); 84 EXPECT_EQ((uint64_t)2, Res.One.getZExtValue()); 85 EXPECT_EQ((uint64_t)0xfc, Res.Zero.getZExtValue()); 86 87 KnownBits Res2 = Info.getKnownBits(DstReg); 88 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 89 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 90 } 91 92 // Check that we report we know nothing when we hit a 93 // non-generic register. 94 // Note: this could be improved though! 95 TEST_F(AArch64GISelMITest, TestKnownBitsCstPHIToNonGenericReg) { 96 StringRef MIRString = " bb.10:\n" 97 " %10:gpr32 = MOVi32imm 3\n" 98 " %11:_(s1) = G_IMPLICIT_DEF\n" 99 " G_BRCOND %11(s1), %bb.11\n" 100 " G_BR %bb.12\n" 101 "\n" 102 " bb.11:\n" 103 " %12:_(s8) = G_CONSTANT i8 2\n" 104 " G_BR %bb.12\n" 105 "\n" 106 " bb.12:\n" 107 " %13:_(s8) = PHI %10, %bb.10, %12(s8), %bb.11\n" 108 " %14:_(s8) = COPY %13\n"; 109 setUp(MIRString); 110 if (!TM) 111 return; 112 Register CopyReg = Copies[Copies.size() - 1]; 113 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 114 Register SrcReg = FinalCopy->getOperand(1).getReg(); 115 Register DstReg = FinalCopy->getOperand(0).getReg(); 116 GISelKnownBits Info(*MF); 117 KnownBits Res = Info.getKnownBits(SrcReg); 118 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 119 EXPECT_EQ((uint64_t)0, Res.Zero.getZExtValue()); 120 121 KnownBits Res2 = Info.getKnownBits(DstReg); 122 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 123 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 124 } 125 126 // Check that we know nothing when at least one value of a PHI 127 // comes from something we cannot analysis. 128 // This test is not particularly interesting, it is just 129 // here to cover the code that stops the analysis of PHIs 130 // earlier. In that case, we would not even look at the 131 // second incoming value. 132 TEST_F(AArch64GISelMITest, TestKnownBitsUnknownPHI) { 133 StringRef MIRString = 134 " bb.10:\n" 135 " %10:_(s64) = COPY %0\n" 136 " %11:_(s1) = G_IMPLICIT_DEF\n" 137 " G_BRCOND %11(s1), %bb.11\n" 138 " G_BR %bb.12\n" 139 "\n" 140 " bb.11:\n" 141 " %12:_(s64) = G_CONSTANT i64 2\n" 142 " G_BR %bb.12\n" 143 "\n" 144 " bb.12:\n" 145 " %13:_(s64) = PHI %10(s64), %bb.10, %12(s64), %bb.11\n" 146 " %14:_(s64) = COPY %13\n"; 147 setUp(MIRString); 148 if (!TM) 149 return; 150 Register CopyReg = Copies[Copies.size() - 1]; 151 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 152 Register SrcReg = FinalCopy->getOperand(1).getReg(); 153 Register DstReg = FinalCopy->getOperand(0).getReg(); 154 GISelKnownBits Info(*MF); 155 KnownBits Res = Info.getKnownBits(SrcReg); 156 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 157 EXPECT_EQ((uint64_t)0, Res.Zero.getZExtValue()); 158 159 KnownBits Res2 = Info.getKnownBits(DstReg); 160 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 161 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 162 } 163 164 // Check that we manage to process PHIs that loop on themselves. 165 // For now, the analysis just stops and assumes it knows nothing, 166 // eventually we could teach it how to properly track phis that 167 // loop back. 168 TEST_F(AArch64GISelMITest, TestKnownBitsCstPHIWithLoop) { 169 StringRef MIRString = 170 " bb.10:\n" 171 " %10:_(s8) = G_CONSTANT i8 3\n" 172 " %11:_(s1) = G_IMPLICIT_DEF\n" 173 " G_BRCOND %11(s1), %bb.11\n" 174 " G_BR %bb.12\n" 175 "\n" 176 " bb.11:\n" 177 " %12:_(s8) = G_CONSTANT i8 2\n" 178 " G_BR %bb.12\n" 179 "\n" 180 " bb.12:\n" 181 " %13:_(s8) = PHI %10(s8), %bb.10, %12(s8), %bb.11, %14(s8), %bb.12\n" 182 " %14:_(s8) = COPY %13\n" 183 " G_BR %bb.12\n"; 184 setUp(MIRString); 185 if (!TM) 186 return; 187 Register CopyReg = Copies[Copies.size() - 1]; 188 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 189 Register SrcReg = FinalCopy->getOperand(1).getReg(); 190 Register DstReg = FinalCopy->getOperand(0).getReg(); 191 GISelKnownBits Info(*MF); 192 KnownBits Res = Info.getKnownBits(SrcReg); 193 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 194 EXPECT_EQ((uint64_t)0, Res.Zero.getZExtValue()); 195 196 KnownBits Res2 = Info.getKnownBits(DstReg); 197 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 198 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 199 } 200 201 // Check that we don't try to analysis PHIs progression. 202 // Setting a deep enough max depth would allow to effectively simulate 203 // what happens in the loop. 204 // Thus, with a deep enough depth, we could actually figure out 205 // that %14's zero known bits are actually at least what we know 206 // for %10, right shifted by one. 207 // However, this process is super expensive compile-time wise and 208 // we don't want to reach that conclusion while playing with max depth. 209 // For now, the analysis just stops and assumes it knows nothing 210 // on PHIs, but eventually we could teach it how to properly track 211 // phis that loop back without relying on the luck effect of max 212 // depth. 213 TEST_F(AArch64GISelMITest, TestKnownBitsDecreasingCstPHIWithLoop) { 214 StringRef MIRString = " bb.10:\n" 215 " %10:_(s8) = G_CONSTANT i8 5\n" 216 " %11:_(s8) = G_CONSTANT i8 1\n" 217 "\n" 218 " bb.12:\n" 219 " %13:_(s8) = PHI %10(s8), %bb.10, %14(s8), %bb.12\n" 220 " %14:_(s8) = G_LSHR %13, %11\n" 221 " %15:_(s8) = COPY %14\n" 222 " G_BR %bb.12\n"; 223 setUp(MIRString); 224 if (!TM) 225 return; 226 Register CopyReg = Copies[Copies.size() - 1]; 227 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 228 Register SrcReg = FinalCopy->getOperand(1).getReg(); 229 Register DstReg = FinalCopy->getOperand(0).getReg(); 230 GISelKnownBits Info(*MF, /*MaxDepth=*/24); 231 KnownBits Res = Info.getKnownBits(SrcReg); 232 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 233 // A single iteration on the PHI (%13) gives: 234 // %10 has known zero of 0xFA 235 // %12 has known zero of 0x80 (we shift right by one so high bit is zero) 236 // Therefore, %14's known zero are 0x80 shifted by one 0xC0. 237 // If we had simulated the loop we could have more zero bits, basically 238 // up to 0xFC (count leading zero of 5, + 1). 239 EXPECT_EQ((uint64_t)0xC0, Res.Zero.getZExtValue()); 240 241 KnownBits Res2 = Info.getKnownBits(DstReg); 242 EXPECT_EQ(Res.One.getZExtValue(), Res2.One.getZExtValue()); 243 EXPECT_EQ(Res.Zero.getZExtValue(), Res2.Zero.getZExtValue()); 244 } 245 246 TEST_F(AArch64GISelMITest, TestKnownBitsPtrToIntViceVersa) { 247 StringRef MIRString = " %3:_(s16) = G_CONSTANT i16 256\n" 248 " %4:_(p0) = G_INTTOPTR %3\n" 249 " %5:_(s32) = G_PTRTOINT %4\n" 250 " %6:_(s32) = COPY %5\n"; 251 setUp(MIRString); 252 if (!TM) 253 return; 254 unsigned CopyReg = Copies[Copies.size() - 1]; 255 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 256 unsigned SrcReg = FinalCopy->getOperand(1).getReg(); 257 GISelKnownBits Info(*MF); 258 KnownBits Res = Info.getKnownBits(SrcReg); 259 EXPECT_EQ(256u, Res.One.getZExtValue()); 260 EXPECT_EQ(0xfffffeffu, Res.Zero.getZExtValue()); 261 } 262 TEST_F(AArch64GISelMITest, TestKnownBitsXOR) { 263 StringRef MIRString = " %3:_(s8) = G_CONSTANT i8 4\n" 264 " %4:_(s8) = G_CONSTANT i8 7\n" 265 " %5:_(s8) = G_XOR %3, %4\n" 266 " %6:_(s8) = COPY %5\n"; 267 setUp(MIRString); 268 if (!TM) 269 return; 270 unsigned CopyReg = Copies[Copies.size() - 1]; 271 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 272 unsigned SrcReg = FinalCopy->getOperand(1).getReg(); 273 GISelKnownBits Info(*MF); 274 KnownBits Res = Info.getKnownBits(SrcReg); 275 EXPECT_EQ(3u, Res.One.getZExtValue()); 276 EXPECT_EQ(252u, Res.Zero.getZExtValue()); 277 } 278 279 TEST_F(AArch64GISelMITest, TestKnownBits) { 280 281 StringRef MIR = " %3:_(s32) = G_TRUNC %0\n" 282 " %4:_(s32) = G_TRUNC %1\n" 283 " %5:_(s32) = G_CONSTANT i32 5\n" 284 " %6:_(s32) = G_CONSTANT i32 24\n" 285 " %7:_(s32) = G_CONSTANT i32 28\n" 286 " %14:_(p0) = G_INTTOPTR %7\n" 287 " %16:_(s32) = G_PTRTOINT %14\n" 288 " %8:_(s32) = G_SHL %3, %5\n" 289 " %9:_(s32) = G_SHL %4, %5\n" 290 " %10:_(s32) = G_OR %8, %6\n" 291 " %11:_(s32) = G_OR %9, %16\n" 292 " %12:_(s32) = G_MUL %10, %11\n" 293 " %13:_(s32) = COPY %12\n"; 294 setUp(MIR); 295 if (!TM) 296 return; 297 unsigned CopyReg = Copies[Copies.size() - 1]; 298 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 299 unsigned SrcReg = FinalCopy->getOperand(1).getReg(); 300 GISelKnownBits Info(*MF); 301 KnownBits Known = Info.getKnownBits(SrcReg); 302 EXPECT_FALSE(Known.hasConflict()); 303 EXPECT_EQ(32u, Known.One.getZExtValue()); 304 EXPECT_EQ(95u, Known.Zero.getZExtValue()); 305 APInt Zeroes = Info.getKnownZeroes(SrcReg); 306 EXPECT_EQ(Known.Zero, Zeroes); 307 } 308 309 TEST_F(AArch64GISelMITest, TestSignBitIsZero) { 310 setUp(); 311 if (!TM) 312 return; 313 314 const LLT S32 = LLT::scalar(32); 315 auto SignBit = B.buildConstant(S32, 0x80000000); 316 auto Zero = B.buildConstant(S32, 0); 317 318 GISelKnownBits KnownBits(*MF); 319 320 EXPECT_TRUE(KnownBits.signBitIsZero(Zero.getReg(0))); 321 EXPECT_FALSE(KnownBits.signBitIsZero(SignBit.getReg(0))); 322 } 323 324 TEST_F(AArch64GISelMITest, TestNumSignBitsConstant) { 325 StringRef MIRString = " %3:_(s8) = G_CONSTANT i8 1\n" 326 " %4:_(s8) = COPY %3\n" 327 328 " %5:_(s8) = G_CONSTANT i8 -1\n" 329 " %6:_(s8) = COPY %5\n" 330 331 " %7:_(s8) = G_CONSTANT i8 127\n" 332 " %8:_(s8) = COPY %7\n" 333 334 " %9:_(s8) = G_CONSTANT i8 32\n" 335 " %10:_(s8) = COPY %9\n" 336 337 " %11:_(s8) = G_CONSTANT i8 -32\n" 338 " %12:_(s8) = COPY %11\n"; 339 setUp(MIRString); 340 if (!TM) 341 return; 342 Register CopyReg1 = Copies[Copies.size() - 5]; 343 Register CopyRegNeg1 = Copies[Copies.size() - 4]; 344 Register CopyReg127 = Copies[Copies.size() - 3]; 345 Register CopyReg32 = Copies[Copies.size() - 2]; 346 Register CopyRegNeg32 = Copies[Copies.size() - 1]; 347 348 GISelKnownBits Info(*MF); 349 EXPECT_EQ(7u, Info.computeNumSignBits(CopyReg1)); 350 EXPECT_EQ(8u, Info.computeNumSignBits(CopyRegNeg1)); 351 EXPECT_EQ(1u, Info.computeNumSignBits(CopyReg127)); 352 EXPECT_EQ(2u, Info.computeNumSignBits(CopyReg32)); 353 EXPECT_EQ(3u, Info.computeNumSignBits(CopyRegNeg32)); 354 } 355 356 TEST_F(AArch64GISelMITest, TestNumSignBitsSext) { 357 StringRef MIRString = " %3:_(p0) = G_IMPLICIT_DEF\n" 358 " %4:_(s8) = G_LOAD %3 :: (load 1)\n" 359 " %5:_(s32) = G_SEXT %4\n" 360 " %6:_(s32) = COPY %5\n" 361 362 " %7:_(s8) = G_CONSTANT i8 -1\n" 363 " %8:_(s32) = G_SEXT %7\n" 364 " %9:_(s32) = COPY %8\n"; 365 setUp(MIRString); 366 if (!TM) 367 return; 368 Register CopySextLoad = Copies[Copies.size() - 2]; 369 Register CopySextNeg1 = Copies[Copies.size() - 1]; 370 371 GISelKnownBits Info(*MF); 372 EXPECT_EQ(25u, Info.computeNumSignBits(CopySextLoad)); 373 EXPECT_EQ(32u, Info.computeNumSignBits(CopySextNeg1)); 374 } 375 376 TEST_F(AArch64GISelMITest, TestNumSignBitsSextInReg) { 377 StringRef MIRString = R"( 378 %ptr:_(p0) = G_IMPLICIT_DEF 379 %load4:_(s32) = G_LOAD %ptr :: (load 4) 380 381 %inreg7:_(s32) = G_SEXT_INREG %load4, 7 382 %copy_inreg7:_(s32) = COPY %inreg7 383 384 %inreg8:_(s32) = G_SEXT_INREG %load4, 8 385 %copy_inreg8:_(s32) = COPY %inreg8 386 387 %inreg9:_(s32) = G_SEXT_INREG %load4, 9 388 %copy_inreg9:_(s32) = COPY %inreg9 389 390 %inreg31:_(s32) = G_SEXT_INREG %load4, 31 391 %copy_inreg31:_(s32) = COPY %inreg31 392 393 %load1:_(s8) = G_LOAD %ptr :: (load 1) 394 %sext_load1:_(s32) = G_SEXT %load1 395 396 %inreg6_sext:_(s32) = G_SEXT_INREG %sext_load1, 6 397 %copy_inreg6_sext:_(s32) = COPY %inreg6_sext 398 399 %inreg7_sext:_(s32) = G_SEXT_INREG %sext_load1, 7 400 %copy_inreg7_sext:_(s32) = COPY %inreg7_sext 401 402 %inreg8_sext:_(s32) = G_SEXT_INREG %sext_load1, 8 403 %copy_inreg8_sext:_(s32) = COPY %inreg8_sext 404 405 %inreg9_sext:_(s32) = G_SEXT_INREG %sext_load1, 9 406 %copy_inreg9_sext:_(s32) = COPY %inreg9_sext 407 408 %inreg31_sext:_(s32) = G_SEXT_INREG %sext_load1, 31 409 %copy_inreg31_sext:_(s32) = COPY %inreg31_sext 410 )"; 411 412 setUp(MIRString); 413 if (!TM) 414 return; 415 416 Register CopyInReg7 = Copies[Copies.size() - 9]; 417 Register CopyInReg8 = Copies[Copies.size() - 8]; 418 Register CopyInReg9 = Copies[Copies.size() - 7]; 419 Register CopyInReg31 = Copies[Copies.size() - 6]; 420 421 Register CopyInReg6Sext = Copies[Copies.size() - 5]; 422 Register CopyInReg7Sext = Copies[Copies.size() - 4]; 423 Register CopyInReg8Sext = Copies[Copies.size() - 3]; 424 Register CopyInReg9Sext = Copies[Copies.size() - 2]; 425 Register CopyInReg31Sext = Copies[Copies.size() - 1]; 426 427 GISelKnownBits Info(*MF); 428 EXPECT_EQ(26u, Info.computeNumSignBits(CopyInReg7)); 429 EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg8)); 430 EXPECT_EQ(24u, Info.computeNumSignBits(CopyInReg9)); 431 EXPECT_EQ(2u, Info.computeNumSignBits(CopyInReg31)); 432 433 EXPECT_EQ(27u, Info.computeNumSignBits(CopyInReg6Sext)); 434 EXPECT_EQ(26u, Info.computeNumSignBits(CopyInReg7Sext)); 435 EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg8Sext)); 436 EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg9Sext)); 437 EXPECT_EQ(25u, Info.computeNumSignBits(CopyInReg31Sext)); 438 } 439 440 TEST_F(AArch64GISelMITest, TestNumSignBitsTrunc) { 441 StringRef MIRString = " %3:_(p0) = G_IMPLICIT_DEF\n" 442 " %4:_(s32) = G_LOAD %3 :: (load 4)\n" 443 " %5:_(s8) = G_TRUNC %4\n" 444 " %6:_(s8) = COPY %5\n" 445 446 " %7:_(s32) = G_CONSTANT i32 -1\n" 447 " %8:_(s8) = G_TRUNC %7\n" 448 " %9:_(s8) = COPY %8\n" 449 450 " %10:_(s32) = G_CONSTANT i32 7\n" 451 " %11:_(s8) = G_TRUNC %10\n" 452 " %12:_(s8) = COPY %11\n"; 453 setUp(MIRString); 454 if (!TM) 455 return; 456 Register CopyTruncLoad = Copies[Copies.size() - 3]; 457 Register CopyTruncNeg1 = Copies[Copies.size() - 2]; 458 Register CopyTrunc7 = Copies[Copies.size() - 1]; 459 460 GISelKnownBits Info(*MF); 461 EXPECT_EQ(1u, Info.computeNumSignBits(CopyTruncLoad)); 462 EXPECT_EQ(8u, Info.computeNumSignBits(CopyTruncNeg1)); 463 EXPECT_EQ(5u, Info.computeNumSignBits(CopyTrunc7)); 464 } 465 466 TEST_F(AMDGPUGISelMITest, TestNumSignBitsTrunc) { 467 StringRef MIRString = 468 " %3:_(<4 x s32>) = G_IMPLICIT_DEF\n" 469 " %4:_(s32) = G_IMPLICIT_DEF\n" 470 " %5:_(s32) = G_AMDGPU_BUFFER_LOAD_UBYTE %3, %4, %4, %4, 0, 0, 0 :: (load 1)\n" 471 " %6:_(s32) = COPY %5\n" 472 473 " %7:_(s32) = G_AMDGPU_BUFFER_LOAD_SBYTE %3, %4, %4, %4, 0, 0, 0 :: (load 1)\n" 474 " %8:_(s32) = COPY %7\n" 475 476 " %9:_(s32) = G_AMDGPU_BUFFER_LOAD_USHORT %3, %4, %4, %4, 0, 0, 0 :: (load 2)\n" 477 " %10:_(s32) = COPY %9\n" 478 479 " %11:_(s32) = G_AMDGPU_BUFFER_LOAD_SSHORT %3, %4, %4, %4, 0, 0, 0 :: (load 2)\n" 480 " %12:_(s32) = COPY %11\n"; 481 482 setUp(MIRString); 483 if (!TM) 484 return; 485 486 Register CopyLoadUByte = Copies[Copies.size() - 4]; 487 Register CopyLoadSByte = Copies[Copies.size() - 3]; 488 Register CopyLoadUShort = Copies[Copies.size() - 2]; 489 Register CopyLoadSShort = Copies[Copies.size() - 1]; 490 491 GISelKnownBits Info(*MF); 492 493 EXPECT_EQ(24u, Info.computeNumSignBits(CopyLoadUByte)); 494 EXPECT_EQ(25u, Info.computeNumSignBits(CopyLoadSByte)); 495 EXPECT_EQ(16u, Info.computeNumSignBits(CopyLoadUShort)); 496 EXPECT_EQ(17u, Info.computeNumSignBits(CopyLoadSShort)); 497 } 498 499 TEST_F(AMDGPUGISelMITest, TestTargetKnownAlign) { 500 StringRef MIRString = 501 " %5:_(p4) = G_INTRINSIC intrinsic(@llvm.amdgcn.dispatch.ptr)\n" 502 " %6:_(p4) = COPY %5\n" 503 " %7:_(p4) = G_INTRINSIC intrinsic(@llvm.amdgcn.queue.ptr)\n" 504 " %8:_(p4) = COPY %7\n" 505 " %9:_(p4) = G_INTRINSIC intrinsic(@llvm.amdgcn.kernarg.segment.ptr)\n" 506 " %10:_(p4) = COPY %9\n" 507 " %11:_(p4) = G_INTRINSIC intrinsic(@llvm.amdgcn.implicitarg.ptr)\n" 508 " %12:_(p4) = COPY %11\n" 509 " %13:_(p4) = G_INTRINSIC intrinsic(@llvm.amdgcn.implicit.buffer.ptr)\n" 510 " %14:_(p4) = COPY %13\n"; 511 512 setUp(MIRString); 513 if (!TM) 514 return; 515 516 Register CopyDispatchPtr = Copies[Copies.size() - 5]; 517 Register CopyQueuePtr = Copies[Copies.size() - 4]; 518 Register CopyKernargSegmentPtr = Copies[Copies.size() - 3]; 519 Register CopyImplicitArgPtr = Copies[Copies.size() - 2]; 520 Register CopyImplicitBufferPtr = Copies[Copies.size() - 1]; 521 522 GISelKnownBits Info(*MF); 523 524 EXPECT_EQ(Align(4), Info.computeKnownAlignment(CopyDispatchPtr)); 525 EXPECT_EQ(Align(4), Info.computeKnownAlignment(CopyQueuePtr)); 526 EXPECT_EQ(Align(4), Info.computeKnownAlignment(CopyKernargSegmentPtr)); 527 EXPECT_EQ(Align(4), Info.computeKnownAlignment(CopyImplicitArgPtr)); 528 EXPECT_EQ(Align(4), Info.computeKnownAlignment(CopyImplicitBufferPtr)); 529 } 530 531 TEST_F(AMDGPUGISelMITest, TestIsKnownToBeAPowerOfTwo) { 532 533 StringRef MIRString = R"MIR( 534 %zero:_(s32) = G_CONSTANT i32 0 535 %one:_(s32) = G_CONSTANT i32 1 536 %two:_(s32) = G_CONSTANT i32 2 537 %three:_(s32) = G_CONSTANT i32 3 538 %five:_(s32) = G_CONSTANT i32 5 539 %copy_zero:_(s32) = COPY %zero 540 %copy_one:_(s32) = COPY %one 541 %copy_two:_(s32) = COPY %two 542 %copy_three:_(s32) = COPY %three 543 544 %trunc_two:_(s1) = G_TRUNC %two 545 %trunc_three:_(s1) = G_TRUNC %three 546 %trunc_five:_(s1) = G_TRUNC %five 547 548 %copy_trunc_two:_(s1) = COPY %trunc_two 549 %copy_trunc_three:_(s1) = COPY %trunc_three 550 %copy_trunc_five:_(s1) = COPY %trunc_five 551 552 %ptr:_(p1) = G_IMPLICIT_DEF 553 %shift_amt:_(s32) = G_LOAD %ptr :: (load 4, addrspace 1) 554 555 %shl_1:_(s32) = G_SHL %one, %shift_amt 556 %copy_shl_1:_(s32) = COPY %shl_1 557 558 %shl_2:_(s32) = G_SHL %two, %shift_amt 559 %copy_shl_2:_(s32) = COPY %shl_2 560 561 %not_sign_mask:_(s32) = G_LOAD %ptr :: (load 4, addrspace 1) 562 %sign_mask:_(s32) = G_CONSTANT i32 -2147483648 563 564 %lshr_not_sign_mask:_(s32) = G_LSHR %not_sign_mask, %shift_amt 565 %copy_lshr_not_sign_mask:_(s32) = COPY %lshr_not_sign_mask 566 567 %lshr_sign_mask:_(s32) = G_LSHR %sign_mask, %shift_amt 568 %copy_lshr_sign_mask:_(s32) = COPY %lshr_sign_mask 569 570 %or_pow2:_(s32) = G_OR %zero, %two 571 %copy_or_pow2:_(s32) = COPY %or_pow2 572 573 )MIR"; 574 setUp(MIRString); 575 if (!TM) 576 return; 577 578 GISelKnownBits KB(*MF); 579 580 Register CopyZero = Copies[Copies.size() - 12]; 581 Register CopyOne = Copies[Copies.size() - 11]; 582 Register CopyTwo = Copies[Copies.size() - 10]; 583 Register CopyThree = Copies[Copies.size() - 9]; 584 Register CopyTruncTwo = Copies[Copies.size() - 8]; 585 Register CopyTruncThree = Copies[Copies.size() - 7]; 586 Register CopyTruncFive = Copies[Copies.size() - 6]; 587 588 Register CopyShl1 = Copies[Copies.size() - 5]; 589 Register CopyShl2 = Copies[Copies.size() - 4]; 590 591 Register CopyLShrNotSignMask = Copies[Copies.size() - 3]; 592 Register CopyLShrSignMask = Copies[Copies.size() - 2]; 593 Register CopyOrPow2 = Copies[Copies.size() - 1]; 594 595 EXPECT_FALSE(isKnownToBeAPowerOfTwo(CopyZero, *MRI, &KB)); 596 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyOne, *MRI, &KB)); 597 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyTwo, *MRI, &KB)); 598 EXPECT_FALSE(isKnownToBeAPowerOfTwo(CopyThree, *MRI, &KB)); 599 600 EXPECT_FALSE(isKnownToBeAPowerOfTwo(CopyTruncTwo, *MRI, &KB)); 601 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyTruncThree, *MRI, &KB)); 602 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyTruncFive, *MRI, &KB)); 603 604 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyShl1, *MRI, &KB)); 605 EXPECT_FALSE(isKnownToBeAPowerOfTwo(CopyShl2, *MRI, &KB)); 606 607 EXPECT_FALSE(isKnownToBeAPowerOfTwo(CopyLShrNotSignMask, *MRI, &KB)); 608 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyLShrSignMask, *MRI, &KB)); 609 EXPECT_TRUE(isKnownToBeAPowerOfTwo(CopyOrPow2, *MRI, &KB)); 610 } 611 612 TEST_F(AArch64GISelMITest, TestMetadata) { 613 StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n" 614 " %load:_(s8) = G_LOAD %imp(p0) :: (load 1)\n" 615 " %ext:_(s32) = G_ZEXT %load(s8)\n" 616 " %cst:_(s32) = G_CONSTANT i32 1\n" 617 " %and:_(s32) = G_AND %ext, %cst\n" 618 " %copy:_(s32) = COPY %and(s32)\n"; 619 setUp(MIRString); 620 if (!TM) 621 return; 622 623 Register CopyReg = Copies[Copies.size() - 1]; 624 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 625 Register SrcReg = FinalCopy->getOperand(1).getReg(); 626 627 // We need a load with a metadata range for this to break. Fudge the load in 628 // the string and replace it with something we can work with. 629 MachineInstr *And = MRI->getVRegDef(SrcReg); 630 MachineInstr *Ext = MRI->getVRegDef(And->getOperand(1).getReg()); 631 MachineInstr *Load = MRI->getVRegDef(Ext->getOperand(1).getReg()); 632 IntegerType *Int8Ty = Type::getInt8Ty(Context); 633 634 // Value must be in [0, 2) 635 Metadata *LowAndHigh[] = { 636 ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 0)), 637 ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 2))}; 638 auto NewMDNode = MDNode::get(Context, LowAndHigh); 639 const MachineMemOperand *OldMMO = *Load->memoperands_begin(); 640 MachineMemOperand NewMMO(OldMMO->getPointerInfo(), OldMMO->getFlags(), 641 OldMMO->getSizeInBits(), OldMMO->getAlign(), 642 OldMMO->getAAInfo(), NewMDNode); 643 MachineIRBuilder MIB(*Load); 644 MIB.buildLoad(Load->getOperand(0), Load->getOperand(1), NewMMO); 645 Load->eraseFromParent(); 646 647 GISelKnownBits Info(*MF); 648 KnownBits Res = Info.getKnownBits(And->getOperand(1).getReg()); 649 650 // We don't know what the result of the load is, so we don't know any ones. 651 EXPECT_TRUE(Res.One.isNullValue()); 652 653 // We know that the value is in [0, 2). So, we don't know if the first bit 654 // is 0 or not. However, we do know that every other bit must be 0. 655 APInt Mask(Res.getBitWidth(), 1); 656 Mask.flipAllBits(); 657 EXPECT_EQ(Mask.getZExtValue(), Res.Zero.getZExtValue()); 658 } 659 660 TEST_F(AArch64GISelMITest, TestKnownBitsExt) { 661 StringRef MIRString = " %c1:_(s16) = G_CONSTANT i16 1\n" 662 " %x:_(s16) = G_IMPLICIT_DEF\n" 663 " %y:_(s16) = G_AND %x, %c1\n" 664 " %anyext:_(s32) = G_ANYEXT %y(s16)\n" 665 " %r1:_(s32) = COPY %anyext\n" 666 " %zext:_(s32) = G_ZEXT %y(s16)\n" 667 " %r2:_(s32) = COPY %zext\n" 668 " %sext:_(s32) = G_SEXT %y(s16)\n" 669 " %r3:_(s32) = COPY %sext\n"; 670 setUp(MIRString); 671 if (!TM) 672 return; 673 Register CopyRegAny = Copies[Copies.size() - 3]; 674 Register CopyRegZ = Copies[Copies.size() - 2]; 675 Register CopyRegS = Copies[Copies.size() - 1]; 676 677 GISelKnownBits Info(*MF); 678 MachineInstr *Copy; 679 Register SrcReg; 680 KnownBits Res; 681 682 Copy = MRI->getVRegDef(CopyRegAny); 683 SrcReg = Copy->getOperand(1).getReg(); 684 Res = Info.getKnownBits(SrcReg); 685 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 686 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 687 EXPECT_EQ((uint64_t)0x0000fffe, Res.Zero.getZExtValue()); 688 689 Copy = MRI->getVRegDef(CopyRegZ); 690 SrcReg = Copy->getOperand(1).getReg(); 691 Res = Info.getKnownBits(SrcReg); 692 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 693 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 694 EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue()); 695 696 Copy = MRI->getVRegDef(CopyRegS); 697 SrcReg = Copy->getOperand(1).getReg(); 698 Res = Info.getKnownBits(SrcReg); 699 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 700 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 701 EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue()); 702 } 703 704 TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) { 705 StringRef MIRString = R"( 706 %val0:_(s16) = G_CONSTANT i16 35224 707 %val1:_(s16) = G_CONSTANT i16 17494 708 %val2:_(s16) = G_CONSTANT i16 4659 709 %val3:_(s16) = G_CONSTANT i16 43981 710 %merge:_(s64) = G_MERGE_VALUES %val0, %val1, %val2, %val3 711 %mergecopy:_(s64) = COPY %merge 712 )"; 713 setUp(MIRString); 714 if (!TM) 715 return; 716 717 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 718 Register CopyMerge = Copies[Copies.size() - 1]; 719 720 GISelKnownBits Info(*MF); 721 KnownBits Res = Info.getKnownBits(CopyMerge); 722 EXPECT_EQ(64u, Res.getBitWidth()); 723 EXPECT_EQ(TestVal, Res.One.getZExtValue()); 724 EXPECT_EQ(~TestVal, Res.Zero.getZExtValue()); 725 } 726 727 TEST_F(AArch64GISelMITest, TestKnownBitsUnmergeValues) { 728 StringRef MIRString = R"( 729 %val:_(s64) = G_CONSTANT i64 12379570962110515608 730 %val0:_(s16), %val1:_(s16), %val2:_(s16), %val3:_(s16) = G_UNMERGE_VALUES %val 731 %part0:_(s16) = COPY %val0 732 %part1:_(s16) = COPY %val1 733 %part2:_(s16) = COPY %val2 734 %part3:_(s16) = COPY %val3 735 736 )"; 737 setUp(MIRString); 738 if (!TM) 739 return; 740 741 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 742 GISelKnownBits Info(*MF); 743 744 int Offset = -4; 745 for (unsigned BitOffset = 0; BitOffset != 64; BitOffset += 16, ++Offset) { 746 Register Part = Copies[Copies.size() + Offset]; 747 KnownBits PartKnown = Info.getKnownBits(Part); 748 EXPECT_EQ(16u, PartKnown.getBitWidth()); 749 750 uint16_t PartTestVal = static_cast<uint16_t>(TestVal >> BitOffset); 751 EXPECT_EQ(PartTestVal, PartKnown.One.getZExtValue()); 752 EXPECT_EQ(static_cast<uint16_t>(~PartTestVal), PartKnown.Zero.getZExtValue()); 753 } 754 } 755 756 TEST_F(AArch64GISelMITest, TestKnownBitsBSwapBitReverse) { 757 StringRef MIRString = R"( 758 %const:_(s32) = G_CONSTANT i32 287454020 759 %bswap:_(s32) = G_BSWAP %const 760 %bitreverse:_(s32) = G_BITREVERSE %const 761 %copy_bswap:_(s32) = COPY %bswap 762 %copy_bitreverse:_(s32) = COPY %bitreverse 763 )"; 764 setUp(MIRString); 765 if (!TM) 766 return; 767 768 const uint32_t TestVal = 0x11223344; 769 770 Register CopyBSwap = Copies[Copies.size() - 2]; 771 Register CopyBitReverse = Copies[Copies.size() - 1]; 772 773 GISelKnownBits Info(*MF); 774 775 KnownBits BSwapKnown = Info.getKnownBits(CopyBSwap); 776 EXPECT_EQ(32u, BSwapKnown.getBitWidth()); 777 EXPECT_EQ(TestVal, BSwapKnown.One.getZExtValue()); 778 EXPECT_EQ(~TestVal, BSwapKnown.Zero.getZExtValue()); 779 780 KnownBits BitReverseKnown = Info.getKnownBits(CopyBitReverse); 781 EXPECT_EQ(32u, BitReverseKnown.getBitWidth()); 782 EXPECT_EQ(TestVal, BitReverseKnown.One.getZExtValue()); 783 EXPECT_EQ(~TestVal, BitReverseKnown.Zero.getZExtValue()); 784 } 785 786 TEST_F(AArch64GISelMITest, TestKnownBitsUMax) { 787 StringRef MIRString = R"( 788 %val:_(s32) = COPY $w0 789 %zext:_(s64) = G_ZEXT %val 790 %const:_(s64) = G_CONSTANT i64 -256 791 %umax:_(s64) = G_UMAX %zext, %const 792 %copy_umax:_(s64) = COPY %umax 793 )"; 794 setUp(MIRString); 795 if (!TM) 796 return; 797 798 Register CopyUMax = Copies[Copies.size() - 1]; 799 GISelKnownBits Info(*MF); 800 801 KnownBits KnownUmax = Info.getKnownBits(CopyUMax); 802 EXPECT_EQ(64u, KnownUmax.getBitWidth()); 803 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 804 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 805 806 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 807 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 808 } 809 810 TEST_F(AArch64GISelMITest, TestInvalidQueries) { 811 StringRef MIRString = R"( 812 %src:_(s32) = COPY $w0 813 %thirty2:_(s32) = G_CONSTANT i32 32 814 %equalSized:_(s32) = G_SHL %src, %thirty2 815 %copy1:_(s32) = COPY %equalSized 816 %thirty3:_(s32) = G_CONSTANT i32 33 817 %biggerSized:_(s32) = G_SHL %src, %thirty3 818 %copy2:_(s32) = COPY %biggerSized 819 )"; 820 setUp(MIRString); 821 if (!TM) 822 return; 823 824 Register EqSizedCopyReg = Copies[Copies.size() - 2]; 825 MachineInstr *EqSizedCopy = MRI->getVRegDef(EqSizedCopyReg); 826 Register EqSizedShl = EqSizedCopy->getOperand(1).getReg(); 827 828 Register BiggerSizedCopyReg = Copies[Copies.size() - 1]; 829 MachineInstr *BiggerSizedCopy = MRI->getVRegDef(BiggerSizedCopyReg); 830 Register BiggerSizedShl = BiggerSizedCopy->getOperand(1).getReg(); 831 832 GISelKnownBits Info(*MF); 833 KnownBits EqSizeRes = Info.getKnownBits(EqSizedShl); 834 KnownBits BiggerSizeRes = Info.getKnownBits(BiggerSizedShl); 835 836 837 // We don't know what the result of the shift is, but we should not crash 838 EXPECT_TRUE(EqSizeRes.One.isNullValue()); 839 EXPECT_TRUE(EqSizeRes.Zero.isNullValue()); 840 841 EXPECT_TRUE(BiggerSizeRes.One.isNullValue()); 842 EXPECT_TRUE(BiggerSizeRes.Zero.isNullValue()); 843 } 844