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
How would you actually use the result? I guess if you freeze the result, you could do some GEP math at that point.
(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.