JIT: Fix GenTree::IsPow2 functions#127615
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
|
There was an assert failure in arm emitter helper func which I still had to address |
| UINT64 lowBitsMask = maxVal - 1; | ||
| UINT64 signBitsMask = ~lowBitsMask | (1ULL << (width - 1)); // The high bits must be set, and the top bit | ||
| // (sign bit) must be set. | ||
| assert((value < maxVal) || ((value & signBitsMask) == signBitsMask)); |
There was a problem hiding this comment.
my understanding it checks that we properly truncated/sign-extended input
There was a problem hiding this comment.
After fixing fgMorphUModToAndSub this assert no longer fires. However I am still not sure why it was done in the first place here. Let me know if I should revert this change. @EgorBo
There was a problem hiding this comment.
Like it asserts the bits in value above 'width' are 0. But why? It seems like a unnecessary limitation. My new impl is still fulfilling the contract of the function.
EgorBo
left a comment
There was a problem hiding this comment.
runtime/src/coreclr/jit/lower.cpp
Lines 4327 to 4329 in bd9e85e
While you change the behavior of this functions to ignore upper bits, it seems like we have uses where that is not expected, we need to inspect them all and fix, otherwise you're introducing a correctness issue
from a quick look, another instance of that in fgMorphUModToAndSub |
|
The problem is I am not even sure what It seems like existing callers of this function want to know if there is only a single bit set. For example the Regarding the RISCV code in lower. I am not sure it is doing what the author intended. // If 'test' is a single bit test...
//
if (bitOp->IsIntegralConstUnsignedPow2())
{
INT64 bit = bitOp->AsIntConCommon()->IntegralValue();
int log2 = BitOperations::Log2((UINT64)bit);
bitOp->AsIntConCommon()->SetIntegralValue(log2);
return true;
}The I think we should add back my |
I think we should just use truncated value in that RISC-V path |
What's the corresponding API for getting such "truncated value"? |
* add UnsignedIntegralValue * use it from IsIntegralConstUnsignedPow2 and riscv bit-opt in lower
IsIntegralConstUnsignedPow2was passing in sign extended value toisPow2. So it wasn't actually unsigned. For example: 1 << 31 would not be recognized as pow2.Add a
UnsignedIntegralValuethat gives the zero-extended literal. Use it inIsIntegralConstUnsignedPow2to fix it's impl.Also use it in
fgMorphUModToAndSuband a place in lower.