New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
InstSimplify: incorrect fold of pointer comparison between globals #49552
Comments
Relevant code is llvm-project/llvm/lib/IR/ConstantFold.cpp Lines 1846 to 1853 in 1d29925
The code is also wrong in that !isNullValue doesn't mean that the index can't be zero, just that it's not known to be zero. Maybe this fold can be dropped entirely? It seems pretty useless to me. |
Here's another one, which folds (x-1) ugt x -> true: define i1 @global_gep_ugt_global_neg_offset() { ERROR: Value mismatch Example: Source:
Target: |
I believe the right way to fix all these folds is https://reviews.llvm.org/D97665, which limits them to inbounds only. While some of them are also valid without inbounds in limited circumstances, I don't think it's worth bothering with the non-inbounds case here. |
I agree; it's not worth it to spend a lot of time with non-inbounds geps. Plus these folds probably don't kick in that often. But, the last transformation I pasted is completely wrong (likely a copy-paste mistake), as it's trying to prove that (x-1) > x. Since x is non-null, that isn't possible. |
I went on a bit of a crusade and deleted a lot of the folds in this function, because they were all subtly incorrect. The one relevant to this report is gone in 6c03178. |
Extended Description
test: Transforms/InstSimplify/ConstProp/icmp-null.ll
The transformation below is only correct if the gep is over i8*, and not with non-byte-sized types. This is correct: https://alive2.llvm.org/ce/z/S_TsHW
@g2 = global 4 bytes, align 4
@g = global 8 bytes, align 4
define i1 @null_gep_ne_global() {
%__constexpr_0 = ptrtoint * @g2 to i64
%gep = gep * null, 8 x i64 %__constexpr_0 ; <-- notice the 8 x
%cmp = icmp ne * %gep, @g
ret i1 %cmp
}
=>
@g2 = global 4 bytes, align 4
@g = global 8 bytes, align 4
define i1 @null_gep_ne_global() {
ret i1 1
}
Transformation doesn't verify!
ERROR: Value mismatch
Example:
Source:
i64 %__constexpr_0 = #x924925b6db6f5564 (10540997870133138788, -7905746203576412828)
i1 %cmp = #x0 (0)
SOURCE MEMORY STATE
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 address: 0
Block 1 > size: 4 align: 4 alloc type: 0 address: 10540997870133138788
Block 2 > size: 8 align: 4 alloc type: 0 address: 10541006666226903840
Target:
Source value: #x0 (0)
Target value: #x1 (1)
The text was updated successfully, but these errors were encountered: