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(0u, Known.One.getZExtValue()); 304 EXPECT_EQ(31u, 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(AArch64GISelMITest, TestMetadata) { 532 StringRef MIRString = " %imp:_(p0) = G_IMPLICIT_DEF\n" 533 " %load:_(s8) = G_LOAD %imp(p0) :: (load 1)\n" 534 " %ext:_(s32) = G_ZEXT %load(s8)\n" 535 " %cst:_(s32) = G_CONSTANT i32 1\n" 536 " %and:_(s32) = G_AND %ext, %cst\n" 537 " %copy:_(s32) = COPY %and(s32)\n"; 538 setUp(MIRString); 539 if (!TM) 540 return; 541 542 Register CopyReg = Copies[Copies.size() - 1]; 543 MachineInstr *FinalCopy = MRI->getVRegDef(CopyReg); 544 Register SrcReg = FinalCopy->getOperand(1).getReg(); 545 546 // We need a load with a metadata range for this to break. Fudge the load in 547 // the string and replace it with something we can work with. 548 MachineInstr *And = MRI->getVRegDef(SrcReg); 549 MachineInstr *Ext = MRI->getVRegDef(And->getOperand(1).getReg()); 550 MachineInstr *Load = MRI->getVRegDef(Ext->getOperand(1).getReg()); 551 IntegerType *Int8Ty = Type::getInt8Ty(Context); 552 553 // Value must be in [0, 2) 554 Metadata *LowAndHigh[] = { 555 ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 0)), 556 ConstantAsMetadata::get(ConstantInt::get(Int8Ty, 2))}; 557 auto NewMDNode = MDNode::get(Context, LowAndHigh); 558 const MachineMemOperand *OldMMO = *Load->memoperands_begin(); 559 MachineMemOperand NewMMO(OldMMO->getPointerInfo(), OldMMO->getFlags(), 560 OldMMO->getSizeInBits(), OldMMO->getAlign(), 561 OldMMO->getAAInfo(), NewMDNode); 562 MachineIRBuilder MIB(*Load); 563 MIB.buildLoad(Load->getOperand(0), Load->getOperand(1), NewMMO); 564 Load->eraseFromParent(); 565 566 GISelKnownBits Info(*MF); 567 KnownBits Res = Info.getKnownBits(And->getOperand(1).getReg()); 568 569 // We don't know what the result of the load is, so we don't know any ones. 570 EXPECT_TRUE(Res.One.isNullValue()); 571 572 // We know that the value is in [0, 2). So, we don't know if the first bit 573 // is 0 or not. However, we do know that every other bit must be 0. 574 APInt Mask(Res.getBitWidth(), 1); 575 Mask.flipAllBits(); 576 EXPECT_EQ(Mask.getZExtValue(), Res.Zero.getZExtValue()); 577 } 578 579 TEST_F(AArch64GISelMITest, TestKnownBitsExt) { 580 StringRef MIRString = " %c1:_(s16) = G_CONSTANT i16 1\n" 581 " %x:_(s16) = G_IMPLICIT_DEF\n" 582 " %y:_(s16) = G_AND %x, %c1\n" 583 " %anyext:_(s32) = G_ANYEXT %y(s16)\n" 584 " %r1:_(s32) = COPY %anyext\n" 585 " %zext:_(s32) = G_ZEXT %y(s16)\n" 586 " %r2:_(s32) = COPY %zext\n" 587 " %sext:_(s32) = G_SEXT %y(s16)\n" 588 " %r3:_(s32) = COPY %sext\n"; 589 setUp(MIRString); 590 if (!TM) 591 return; 592 Register CopyRegAny = Copies[Copies.size() - 3]; 593 Register CopyRegZ = Copies[Copies.size() - 2]; 594 Register CopyRegS = Copies[Copies.size() - 1]; 595 596 GISelKnownBits Info(*MF); 597 MachineInstr *Copy; 598 Register SrcReg; 599 KnownBits Res; 600 601 Copy = MRI->getVRegDef(CopyRegAny); 602 SrcReg = Copy->getOperand(1).getReg(); 603 Res = Info.getKnownBits(SrcReg); 604 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 605 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 606 EXPECT_EQ((uint64_t)0x0000fffe, Res.Zero.getZExtValue()); 607 608 Copy = MRI->getVRegDef(CopyRegZ); 609 SrcReg = Copy->getOperand(1).getReg(); 610 Res = Info.getKnownBits(SrcReg); 611 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 612 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 613 EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue()); 614 615 Copy = MRI->getVRegDef(CopyRegS); 616 SrcReg = Copy->getOperand(1).getReg(); 617 Res = Info.getKnownBits(SrcReg); 618 EXPECT_EQ((uint64_t)32, Res.getBitWidth()); 619 EXPECT_EQ((uint64_t)0, Res.One.getZExtValue()); 620 EXPECT_EQ((uint64_t)0xfffffffe, Res.Zero.getZExtValue()); 621 } 622 623 TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) { 624 StringRef MIRString = R"( 625 %val0:_(s16) = G_CONSTANT i16 35224 626 %val1:_(s16) = G_CONSTANT i16 17494 627 %val2:_(s16) = G_CONSTANT i16 4659 628 %val3:_(s16) = G_CONSTANT i16 43981 629 %merge:_(s64) = G_MERGE_VALUES %val0, %val1, %val2, %val3 630 %mergecopy:_(s64) = COPY %merge 631 )"; 632 setUp(MIRString); 633 if (!TM) 634 return; 635 636 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 637 Register CopyMerge = Copies[Copies.size() - 1]; 638 639 GISelKnownBits Info(*MF); 640 KnownBits Res = Info.getKnownBits(CopyMerge); 641 EXPECT_EQ(64u, Res.getBitWidth()); 642 EXPECT_EQ(TestVal, Res.One.getZExtValue()); 643 EXPECT_EQ(~TestVal, Res.Zero.getZExtValue()); 644 } 645 646 TEST_F(AArch64GISelMITest, TestKnownBitsUnmergeValues) { 647 StringRef MIRString = R"( 648 %val:_(s64) = G_CONSTANT i64 12379570962110515608 649 %val0:_(s16), %val1:_(s16), %val2:_(s16), %val3:_(s16) = G_UNMERGE_VALUES %val 650 %part0:_(s16) = COPY %val0 651 %part1:_(s16) = COPY %val1 652 %part2:_(s16) = COPY %val2 653 %part3:_(s16) = COPY %val3 654 655 )"; 656 setUp(MIRString); 657 if (!TM) 658 return; 659 660 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 661 GISelKnownBits Info(*MF); 662 663 int Offset = -4; 664 for (unsigned BitOffset = 0; BitOffset != 64; BitOffset += 16, ++Offset) { 665 Register Part = Copies[Copies.size() + Offset]; 666 KnownBits PartKnown = Info.getKnownBits(Part); 667 EXPECT_EQ(16u, PartKnown.getBitWidth()); 668 669 uint16_t PartTestVal = static_cast<uint16_t>(TestVal >> BitOffset); 670 EXPECT_EQ(PartTestVal, PartKnown.One.getZExtValue()); 671 EXPECT_EQ(static_cast<uint16_t>(~PartTestVal), PartKnown.Zero.getZExtValue()); 672 } 673 } 674 675 TEST_F(AArch64GISelMITest, TestKnownBitsBSwapBitReverse) { 676 StringRef MIRString = R"( 677 %const:_(s32) = G_CONSTANT i32 287454020 678 %bswap:_(s32) = G_BSWAP %const 679 %bitreverse:_(s32) = G_BITREVERSE %const 680 %copy_bswap:_(s32) = COPY %bswap 681 %copy_bitreverse:_(s32) = COPY %bitreverse 682 )"; 683 setUp(MIRString); 684 if (!TM) 685 return; 686 687 const uint32_t TestVal = 0x11223344; 688 689 Register CopyBSwap = Copies[Copies.size() - 2]; 690 Register CopyBitReverse = Copies[Copies.size() - 1]; 691 692 GISelKnownBits Info(*MF); 693 694 KnownBits BSwapKnown = Info.getKnownBits(CopyBSwap); 695 EXPECT_EQ(32u, BSwapKnown.getBitWidth()); 696 EXPECT_EQ(TestVal, BSwapKnown.One.getZExtValue()); 697 EXPECT_EQ(~TestVal, BSwapKnown.Zero.getZExtValue()); 698 699 KnownBits BitReverseKnown = Info.getKnownBits(CopyBitReverse); 700 EXPECT_EQ(32u, BitReverseKnown.getBitWidth()); 701 EXPECT_EQ(TestVal, BitReverseKnown.One.getZExtValue()); 702 EXPECT_EQ(~TestVal, BitReverseKnown.Zero.getZExtValue()); 703 } 704 705 TEST_F(AArch64GISelMITest, TestKnownBitsUMax) { 706 StringRef MIRString = R"( 707 %val:_(s32) = COPY $w0 708 %zext:_(s64) = G_ZEXT %val 709 %const:_(s64) = G_CONSTANT i64 -256 710 %umax:_(s64) = G_UMAX %zext, %const 711 %copy_umax:_(s64) = COPY %umax 712 )"; 713 setUp(MIRString); 714 if (!TM) 715 return; 716 717 Register CopyUMax = Copies[Copies.size() - 1]; 718 GISelKnownBits Info(*MF); 719 720 KnownBits KnownUmax = Info.getKnownBits(CopyUMax); 721 EXPECT_EQ(64u, KnownUmax.getBitWidth()); 722 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 723 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 724 725 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 726 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 727 } 728 729 TEST_F(AArch64GISelMITest, TestInvalidQueries) { 730 StringRef MIRString = R"( 731 %src:_(s32) = COPY $w0 732 %thirty2:_(s32) = G_CONSTANT i32 32 733 %equalSized:_(s32) = G_SHL %src, %thirty2 734 %copy1:_(s32) = COPY %equalSized 735 %thirty3:_(s32) = G_CONSTANT i32 33 736 %biggerSized:_(s32) = G_SHL %src, %thirty3 737 %copy2:_(s32) = COPY %biggerSized 738 )"; 739 setUp(MIRString); 740 if (!TM) 741 return; 742 743 Register EqSizedCopyReg = Copies[Copies.size() - 2]; 744 MachineInstr *EqSizedCopy = MRI->getVRegDef(EqSizedCopyReg); 745 Register EqSizedShl = EqSizedCopy->getOperand(1).getReg(); 746 747 Register BiggerSizedCopyReg = Copies[Copies.size() - 1]; 748 MachineInstr *BiggerSizedCopy = MRI->getVRegDef(BiggerSizedCopyReg); 749 Register BiggerSizedShl = BiggerSizedCopy->getOperand(1).getReg(); 750 751 GISelKnownBits Info(*MF); 752 KnownBits EqSizeRes = Info.getKnownBits(EqSizedShl); 753 KnownBits BiggerSizeRes = Info.getKnownBits(BiggerSizedShl); 754 755 756 // We don't know what the result of the shift is, but we should not crash 757 EXPECT_TRUE(EqSizeRes.One.isNullValue()); 758 EXPECT_TRUE(EqSizeRes.Zero.isNullValue()); 759 760 EXPECT_TRUE(BiggerSizeRes.One.isNullValue()); 761 EXPECT_TRUE(BiggerSizeRes.Zero.isNullValue()); 762 } 763