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, TestKnownBitsSextInReg) { 705 StringRef MIRString = R"( 706 ; 000...0001 707 %one:_(s32) = G_CONSTANT i32 1 708 709 ; 000...0010 710 %two:_(s32) = G_CONSTANT i32 2 711 712 ; 000...1010 713 %ten:_(s32) = G_CONSTANT i32 10 714 715 ; ???...???? 716 %w0:_(s32) = COPY $w0 717 718 ; ???...?1? 719 %or:_(s32) = G_OR %w0, %two 720 721 ; All bits are known. 722 %inreg1:_(s32) = G_SEXT_INREG %one, 1 723 %copy_inreg1:_(s32) = COPY %inreg1 724 725 ; All bits unknown 726 %inreg2:_(s32) = G_SEXT_INREG %or, 1 727 %copy_inreg2:_(s32) = COPY %inreg2 728 729 ; Extending from the only (known) set bit 730 ; 111...11? 731 %inreg3:_(s32) = G_SEXT_INREG %or, 2 732 %copy_inreg3:_(s32) = COPY %inreg3 733 734 ; Extending from a known set bit, overwriting all of the high set bits. 735 ; 111...1110 736 %inreg4:_(s32) = G_SEXT_INREG %ten, 2 737 %copy_inreg4:_(s32) = COPY %inreg4 738 739 )"; 740 setUp(MIRString); 741 if (!TM) 742 return; 743 GISelKnownBits Info(*MF); 744 KnownBits Res; 745 auto GetKB = [&](unsigned Idx) { 746 Register CopyReg = Copies[Idx]; 747 auto *Copy = MRI->getVRegDef(CopyReg); 748 return Info.getKnownBits(Copy->getOperand(1).getReg()); 749 }; 750 751 // Every bit is known to be a 1. 752 Res = GetKB(Copies.size() - 4); 753 EXPECT_EQ(32u, Res.getBitWidth()); 754 EXPECT_TRUE(Res.isAllOnes()); 755 756 // All bits are unknown 757 Res = GetKB(Copies.size() - 3); 758 EXPECT_EQ(32u, Res.getBitWidth()); 759 EXPECT_TRUE(Res.isUnknown()); 760 761 // Extending from the only known set bit 762 // 111...11? 763 Res = GetKB(Copies.size() - 2); 764 EXPECT_EQ(32u, Res.getBitWidth()); 765 EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue()); 766 EXPECT_EQ(0u, Res.Zero.getZExtValue()); 767 768 // Extending from a known set bit, overwriting all of the high set bits. 769 // 111...1110 770 Res = GetKB(Copies.size() - 1); 771 EXPECT_EQ(32u, Res.getBitWidth()); 772 EXPECT_EQ(0xFFFFFFFEu, Res.One.getZExtValue()); 773 EXPECT_EQ(1u, Res.Zero.getZExtValue()); 774 } 775 776 TEST_F(AArch64GISelMITest, TestKnownBitsMergeValues) { 777 StringRef MIRString = R"( 778 %val0:_(s16) = G_CONSTANT i16 35224 779 %val1:_(s16) = G_CONSTANT i16 17494 780 %val2:_(s16) = G_CONSTANT i16 4659 781 %val3:_(s16) = G_CONSTANT i16 43981 782 %merge:_(s64) = G_MERGE_VALUES %val0, %val1, %val2, %val3 783 %mergecopy:_(s64) = COPY %merge 784 )"; 785 setUp(MIRString); 786 if (!TM) 787 return; 788 789 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 790 Register CopyMerge = Copies[Copies.size() - 1]; 791 792 GISelKnownBits Info(*MF); 793 KnownBits Res = Info.getKnownBits(CopyMerge); 794 EXPECT_EQ(64u, Res.getBitWidth()); 795 EXPECT_EQ(TestVal, Res.One.getZExtValue()); 796 EXPECT_EQ(~TestVal, Res.Zero.getZExtValue()); 797 } 798 799 TEST_F(AArch64GISelMITest, TestKnownBitsUnmergeValues) { 800 StringRef MIRString = R"( 801 %val:_(s64) = G_CONSTANT i64 12379570962110515608 802 %val0:_(s16), %val1:_(s16), %val2:_(s16), %val3:_(s16) = G_UNMERGE_VALUES %val 803 %part0:_(s16) = COPY %val0 804 %part1:_(s16) = COPY %val1 805 %part2:_(s16) = COPY %val2 806 %part3:_(s16) = COPY %val3 807 808 )"; 809 setUp(MIRString); 810 if (!TM) 811 return; 812 813 const uint64_t TestVal = UINT64_C(0xabcd123344568998); 814 GISelKnownBits Info(*MF); 815 816 int Offset = -4; 817 for (unsigned BitOffset = 0; BitOffset != 64; BitOffset += 16, ++Offset) { 818 Register Part = Copies[Copies.size() + Offset]; 819 KnownBits PartKnown = Info.getKnownBits(Part); 820 EXPECT_EQ(16u, PartKnown.getBitWidth()); 821 822 uint16_t PartTestVal = static_cast<uint16_t>(TestVal >> BitOffset); 823 EXPECT_EQ(PartTestVal, PartKnown.One.getZExtValue()); 824 EXPECT_EQ(static_cast<uint16_t>(~PartTestVal), PartKnown.Zero.getZExtValue()); 825 } 826 } 827 828 TEST_F(AArch64GISelMITest, TestKnownBitsBSwapBitReverse) { 829 StringRef MIRString = R"( 830 %const:_(s32) = G_CONSTANT i32 287454020 831 %bswap:_(s32) = G_BSWAP %const 832 %bitreverse:_(s32) = G_BITREVERSE %const 833 %copy_bswap:_(s32) = COPY %bswap 834 %copy_bitreverse:_(s32) = COPY %bitreverse 835 )"; 836 setUp(MIRString); 837 if (!TM) 838 return; 839 840 const uint32_t TestVal = 0x11223344; 841 842 Register CopyBSwap = Copies[Copies.size() - 2]; 843 Register CopyBitReverse = Copies[Copies.size() - 1]; 844 845 GISelKnownBits Info(*MF); 846 847 KnownBits BSwapKnown = Info.getKnownBits(CopyBSwap); 848 EXPECT_EQ(32u, BSwapKnown.getBitWidth()); 849 EXPECT_EQ(TestVal, BSwapKnown.One.getZExtValue()); 850 EXPECT_EQ(~TestVal, BSwapKnown.Zero.getZExtValue()); 851 852 KnownBits BitReverseKnown = Info.getKnownBits(CopyBitReverse); 853 EXPECT_EQ(32u, BitReverseKnown.getBitWidth()); 854 EXPECT_EQ(TestVal, BitReverseKnown.One.getZExtValue()); 855 EXPECT_EQ(~TestVal, BitReverseKnown.Zero.getZExtValue()); 856 } 857 858 TEST_F(AArch64GISelMITest, TestKnownBitsUMax) { 859 StringRef MIRString = R"( 860 %val:_(s32) = COPY $w0 861 %zext:_(s64) = G_ZEXT %val 862 %const:_(s64) = G_CONSTANT i64 -256 863 %umax:_(s64) = G_UMAX %zext, %const 864 %copy_umax:_(s64) = COPY %umax 865 )"; 866 setUp(MIRString); 867 if (!TM) 868 return; 869 870 Register CopyUMax = Copies[Copies.size() - 1]; 871 GISelKnownBits Info(*MF); 872 873 KnownBits KnownUmax = Info.getKnownBits(CopyUMax); 874 EXPECT_EQ(64u, KnownUmax.getBitWidth()); 875 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 876 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 877 878 EXPECT_EQ(0xffu, KnownUmax.Zero.getZExtValue()); 879 EXPECT_EQ(0xffffffffffffff00, KnownUmax.One.getZExtValue()); 880 } 881 882 TEST_F(AArch64GISelMITest, TestInvalidQueries) { 883 StringRef MIRString = R"( 884 %src:_(s32) = COPY $w0 885 %thirty2:_(s32) = G_CONSTANT i32 32 886 %equalSized:_(s32) = G_SHL %src, %thirty2 887 %copy1:_(s32) = COPY %equalSized 888 %thirty3:_(s32) = G_CONSTANT i32 33 889 %biggerSized:_(s32) = G_SHL %src, %thirty3 890 %copy2:_(s32) = COPY %biggerSized 891 )"; 892 setUp(MIRString); 893 if (!TM) 894 return; 895 896 Register EqSizedCopyReg = Copies[Copies.size() - 2]; 897 MachineInstr *EqSizedCopy = MRI->getVRegDef(EqSizedCopyReg); 898 Register EqSizedShl = EqSizedCopy->getOperand(1).getReg(); 899 900 Register BiggerSizedCopyReg = Copies[Copies.size() - 1]; 901 MachineInstr *BiggerSizedCopy = MRI->getVRegDef(BiggerSizedCopyReg); 902 Register BiggerSizedShl = BiggerSizedCopy->getOperand(1).getReg(); 903 904 GISelKnownBits Info(*MF); 905 KnownBits EqSizeRes = Info.getKnownBits(EqSizedShl); 906 KnownBits BiggerSizeRes = Info.getKnownBits(BiggerSizedShl); 907 908 909 // We don't know what the result of the shift is, but we should not crash 910 EXPECT_TRUE(EqSizeRes.One.isNullValue()); 911 EXPECT_TRUE(EqSizeRes.Zero.isNullValue()); 912 913 EXPECT_TRUE(BiggerSizeRes.One.isNullValue()); 914 EXPECT_TRUE(BiggerSizeRes.Zero.isNullValue()); 915 } 916