Skip to content
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

Closed
nunoplopes opened this issue May 3, 2021 · 5 comments
Closed

InstSimplify: incorrect fold of pointer comparison between globals #49552

nunoplopes opened this issue May 3, 2021 · 5 comments
Labels
bugzilla Issues migrated from bugzilla miscompilation

Comments

@nunoplopes
Copy link
Member

Bugzilla Link 50208
Version trunk
OS All
CC @aqjune,@RKSimon,@nikic,@rotateright

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)

  • %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)

@nikic
Copy link
Contributor

nikic commented May 3, 2021

Relevant code is

// If we are indexing from a null pointer, check to see if we have any
// non-zero indices.
for (unsigned i = 1, e = CE1->getNumOperands(); i != e; ++i)
if (!CE1->getOperand(i)->isNullValue())
// Offsetting from null, must not be equal.
return ICmpInst::ICMP_UGT;
// Only zero indexes from null, must still be zero.
return ICmpInst::ICMP_EQ;
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.

@nunoplopes
Copy link
Member Author

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)

@nikic
Copy link
Contributor

nikic commented May 9, 2021

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.

@nunoplopes
Copy link
Member Author

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.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@nikic
Copy link
Contributor

nikic commented Jan 4, 2022

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.

@nikic nikic closed this as completed Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla miscompilation
Projects
None yet
Development

No branches or pull requests

2 participants