LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 45445 - gep(ptr, undef) isn't undef
Summary: gep(ptr, undef) isn't undef
Status: NEW
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: All All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords: miscompilation
Depends on:
Blocks: 47948
  Show dependency tree
 
Reported: 2020-04-06 06:33 PDT by Nuno Lopes
Modified: 2020-10-22 09:46 PDT (History)
7 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nuno Lopes 2020-04-06 06:33:17 PDT
Test: Transforms/InstCombine/vec_demanded_elts.ll
Summary: gep(ptr, undef) isn't undef. It's a pointer based on ptr with an undef offset (a multiple of 4 in this case). A way to make this correct is to return <%base, %base>.


define <2 x *> @gep_all_lanes_undef(* %base, i64 %idx) {
  %basevec = insertelement <2 x *> undef, * %base, i32 0
  %idxvec = insertelement <2 x i64> undef, i64 %idx, i32 1
  %gep = gep <2 x *> %basevec, 4 x <2 x i64> %idxvec
  ret <2 x *> %gep
}
=>
define <2 x *> @gep_all_lanes_undef(* %base, i64 %idx) {
  ret <2 x *> undef
}

Transformation doesn't verify!
ERROR: Value mismatch

Example:
* %base = pointer(non-local, block_id=1, offset=0)
i64 %idx = #x0000000000080000 (524288)

Source:
<2 x *> %basevec = < pointer(non-local, block_id=1, offset=0), null >
<2 x i64> %idxvec = < undef, #x0000000000080000 (524288) >
<2 x *> %gep = < pointer(non-local, block_id=1, offset=0), pointer(non-local, block_id=0, offset=2097152) >

Target:
Source value: < pointer(non-local, block_id=1, offset=0), pointer(non-local, block_id=0, offset=2097152) >
Target value: < pointer(non-local, block_id=0, offset=16), null >


https://web.ist.utl.pt/nuno.lopes/alive2/index.php?hash=2009353267698970&test=Transforms%2FInstCombine%2Fvec_demanded_elts.ll
Comment 1 Eli Friedman 2020-04-06 11:20:23 PDT
How would you actually use the result?  I guess if you freeze the result, you could do some GEP math at that point.
Comment 2 Nuno Lopes 2020-04-07 01:06:26 PDT
(In reply to Eli Friedman from comment #1)
> How would you actually use the result?  I guess if you freeze the result,
> you could do some GEP math at that point.

A simple example is ptrtoint. These two are different:
%p = gep i32* undef, %idx
%i = ptrtoint %p
=>
%i = ptrtoint undef

Before, %i was a multiple of 4, after it can be any number.

There are more complex examples involving pointer comparison, but I guess the one above is sufficient to show that the transformation is incorrect. Even if it seems harmless.