Open
Description
This example returns a constant value out of range:
define range(i32 0, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 43
}
Running opt -S -p='attributor'
gives an incorrect result:
define noundef range(i32 0, 42) i32 @fn() {
ret i32 43
}
opt -S -p='function-attrs'
has the same bug.
Activity
nikic commentedon Apr 10, 2024
Nice find! This is not specific to the new range attribute, we can do the same thing with nonnull for example: https://llvm.godbolt.org/z/4hz8PEoav
Looks like we entirely failed to account for the possibility that a poison value gets introduced by a return attribute in this inference!
[FunctionAttrs] Add tests for incorrect noundef inference (#88026)
[FunctionAttrs] Fix incorrect noundef inference with poison attrs
[FunctionAttrs] Fix incorrect noundef inference with poison attrs (#8…
nunoplopes commentedon May 10, 2024
Another one with nocapture from @regehr:
antoniofrighetto commentedon May 10, 2024
Untested, but maybe something like this should work:
nikic commentedon May 10, 2024
@nunoplopes Not sure I get this one -- I would expect nocapture to be UB-implying, not poison generating. I don't get how it can be poison-generating, given that nocapture is generally used by the caller, not the callee.
nunoplopes commentedon May 10, 2024
I was debating here with myself.
But let's assume the caller:
If 1 & 2 happen, then we get UB if the usage is a load/store. Any other operation like icmp that uses the pointer are poison. If the caller doesn't use the returned pointer, then it's irrelevant whether it's poison or UB as the assumption in 1) holds.
If inlining happens, the return may be replaced with the argument. That's ok as we are then refining poison into a concrete value.
In summary, yielding poison when nocapture is violated seems sufficient.