This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Fix Incorrect fold of ashr+xor -> lshr w/ vectors
ClosedPublic

Authored by jroelofs on Mar 25 2020, 1:54 PM.

Diff Detail

Event Timeline

jroelofs created this revision.Mar 25 2020, 1:54 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 25 2020, 1:54 PM
jroelofs retitled this revision from [Instcombine] Fix Incorrect fold of ashr+xor -> lshr w/ vectors to [InstCombine] Fix Incorrect fold of ashr+xor -> lshr w/ vectors.Mar 25 2020, 1:54 PM
lebedev.ri requested changes to this revision.Mar 25 2020, 2:08 PM

What we need to do here is "define" undef to be 0.

----------------------------------------
define <4 x i5> @test_v4i5_not_ashr_negative_const_undef(<4 x i5> %a0) {
%0:
  %1 = ashr <4 x i5> { 29, 27, undef, 23 }, %a0
  %2 = xor <4 x i5> { 31, 31, 31, undef }, %1
  ret <4 x i5> %2
}
=>
define <4 x i5> @test_v4i5_not_ashr_negative_const_undef(<4 x i5> %a0) {
%0:
  %1 = lshr <4 x i5> { 2, 4, 0, 8 }, %a0
  ret <4 x i5> %1
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 Alive2 errors

There was some utility for that already, but i don't recall how it's called..

This revision now requires changes to proceed.Mar 25 2020, 2:08 PM
spatel added a subscriber: spatel.Mar 25 2020, 2:17 PM

What we need to do here is "define" undef to be 0.

----------------------------------------
define <4 x i5> @test_v4i5_not_ashr_negative_const_undef(<4 x i5> %a0) {
%0:
  %1 = ashr <4 x i5> { 29, 27, undef, 23 }, %a0
  %2 = xor <4 x i5> { 31, 31, 31, undef }, %1
  ret <4 x i5> %2
}
=>
define <4 x i5> @test_v4i5_not_ashr_negative_const_undef(<4 x i5> %a0) {
%0:
  %1 = lshr <4 x i5> { 2, 4, 0, 8 }, %a0
  ret <4 x i5> %1
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 Alive2 errors

There was some utility for that already, but i don't recall how it's called..

Probably want this:

/// Some binary operators require special handling to avoid poison and undefined
/// behavior. If a constant vector has undef elements, replace those undefs with
/// identity constants if possible because those are always safe to execute.
/// If no identity constant exists, replace undef with some other safe constant.
static inline Constant *getSafeVectorConstantForBinop()
RKSimon added a subscriber: RKSimon.
RKSimon added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
3071–3072

m_Negative uses cst_pred_ty internally which just continues if it finds an undef in a vector - maybe we don't want that?

static inline Constant *getSafeVectorConstantForBinop()

Yes, i think that's the one.

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
3071–3072

We only need to handle undefs correctly, we don't need to completely give up on them here.

jroelofs updated this revision to Diff 252687.Mar 25 2020, 3:13 PM

Implement review feedback

lebedev.ri accepted this revision.Mar 25 2020, 11:39 PM

LG, thank you.

This revision is now accepted and ready to land.Mar 25 2020, 11:39 PM