Issue |
156289
|
Summary |
[GlobalIsel] Assertion when calling `GISelValueTracking::computeNumSignBits` within `GISelValueTracking::computeKnownBitsImpl`
|
Labels |
new issue
|
Assignees |
|
Reporter |
r41k0u
|
I came across this while working on #154413. The tests where `G_ABS` is performed on a `G_CONSTANT` were fine, but everything else failed to generate using the update_givaluetracking_test_checks script.
The mentioned PR does the following changes in `GISelValueTracking::computeKnownBitsImpl`:
```
case TargetOpcode::G_ABS: {
Register SrcReg = MI.getOperand(1).getReg();
computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
Known = Known.abs();
Known.Zero.setHighBits(computeNumSignBits(SrcReg, DemandedElts, Depth + 1) -
1);
break;
}
```
The `Known.Zero.setHighBits` is a fix for https://github.com/llvm/llvm-project/issues/94344.
If we check `GISelValueTracking::computeNumSignBits`:
```
unsigned GISelValueTracking::computeNumSignBits(Register R,
const APInt &DemandedElts,
unsigned Depth) {
MachineInstr &MI = *MRI.getVRegDef(R);
unsigned Opcode = MI.getOpcode();
if (Opcode == TargetOpcode::G_CONSTANT)
return MI.getOperand(1).getCImm()->getValue().getNumSignBits();
```
The constant case gets short-circuited at the top, but:
```
// Finally, if we can prove that the top bits of the result are 0's or 1's,
// use this information.
KnownBits Known = getKnownBits(R, DemandedElts, Depth);
APInt Mask;
if (Known.isNonNegative()) { // sign bit is 0
Mask = Known.Zero;
} else if (Known.isNegative()) { // sign bit is 1;
Mask = Known.One;
} else {
// Nothing known.
return FirstAnswer;
}
// Okay, we know that the sign bit in Mask is set. Use CLO to determine
// the number of identical bits in the top of the input value.
Mask <<= Mask.getBitWidth() - TyBits;
return std::max(FirstAnswer, Mask.countl_one());
}
```
We have a call to `GISelValueTracking::getKnownBits`, which has the following assertion:
```
KnownBits GISelValueTracking::getKnownBits(Register R,
const APInt &DemandedElts,
unsigned Depth) {
// For now, we only maintain the cache during one request.
assert(ComputeKnownBitsCache.empty() && "Cache should have been cleared");
KnownBits Known;
computeKnownBitsImpl(R, Known, DemandedElts, Depth);
ComputeKnownBitsCache.clear();
return Known;
}
```
This also shows up in the stack dump of the failed assertion while running the tests:
```
#8 0x0000ffffb12e00dc __assert_fail_base ./assert/assert.c:53:15
#9 0x0000aaaab8f44de4 llvm::GISelValueTracking::getKnownBits(llvm::Register, llvm::APInt const&, unsigned int) llvm-project/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp:99:13
#10 0x0000aaaab8f4c7dc llvm::GISelValueTracking::computeNumSignBits(llvm::Register, llvm::APInt const&, unsigned int) llvm-project/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp:2049:9
#11 0x0000aaaab8f47cd4 llvm::GISelValueTracking::computeKnownBitsImpl(llvm::Register, llvm::KnownBits&, llvm::APInt const&, unsigned int) llvm-project/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp:704:27
#12 0x0000aaaab8f44e14 llvm::GISelValueTracking::getKnownBits(llvm::Register, llvm::APInt const&, unsigned int) llvm-project/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp:101:30
#13 0x0000aaaab8f44d48 llvm::GISelValueTracking::getKnownBits(llvm::Register)
```
I think one fix is to use `GISelValueTracking::computeKnownBitsImpl` instead of `GISelValueTracking::getKnownBits here, which won't trigger assertions.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs