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) * %gep = pointer(non-local, block_id=0, offset=-7905737407482647776) 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)
Relevant code is https://github.com/llvm/llvm-project/blob/1d299252dd52ade0e87485be29443aa69be9e910/llvm/lib/IR/ConstantFold.cpp#L1846-L1853 I think. 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() { %gep = gep * @g, 8 x i64 -1 %cmp = icmp ugt * %gep, @g ret i1 %cmp } => define i1 @global_gep_ugt_global_neg_offset() { ret i1 1 } Transformation doesn't verify! ERROR: Value mismatch Example: Source: * %gep = pointer(non-local, block_id=0, offset=-8) i1 %cmp = #x0 (0) Target: Source value: #x0 (0) Target value: #x1 (1)
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.
(In reply to Nikita Popov from comment #3) > 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.