This is an archive of the discontinued LLVM Phabricator instance.

[AArch64 NEON] Invalid constant is used in vselect condition.
ClosedPublic

Authored by kevin.qin on Jan 3 2014, 1:57 AM.

Details

Reviewers
andreadb
Summary

Hi,

In AArch64 backend, If the conditions of vselect are vector constant, then the value of "true" is presented as (i8 1) instead of (i8 255) which we expect.
The reason is, vselect only accept vxi1 as condition operand while BSL use every bit of condition to make select. So legalizer will insert a sign_extend_inreg to promote vxi1 to vxi8. Next DAGCombiner will use visitSIGN_EXTEND_INREG() to combine it with a build_vector. Because in AArch64, i8 is illegal, constants with i1 are directly promoted to i32, so for i32, left shift 7 and then arithmetic right shift 7 can't correctly sign_extend i1 to i8.

Diff Detail

Event Timeline

Hi Kevin,

your patch looks good to me.
My original code worked under the wrong assumption that the vector element type and the type of each ConstantSDNode in the build_vector were the same.
However, when promoting the integer operand of a legally typed build_vector, the operand type and the vector element type do not need to be the same (See method 'DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR' in LegalizeIntegerTypes.cpp).

in AArch64 backend, the following dag sequence:

C0: i1 = Constant<0>
C1: i1 = Constant<-1>
V: v8i1 = BUILD_VECTOR C1, C1, C0, C0, C0, C0, C0, C0

is type-legalized into:

NewC0: i32 = Constant<0>
NewC1: i32 = Constant<1>
V: v8i8 = BUILD_VECTOR NewC1, NewC1, NewC0, NewC0, NewC0, NewC0, NewC0, NewC0

Forcing a getZeroExtend to VTBits to ensure that the new constant is correctly generated looks good to me!

Thanks,
Andrea Di Biagio

andreadb accepted this revision.Jan 4 2014, 3:17 AM
Eugene.Zelenko closed this revision.Oct 4 2016, 4:25 PM
Eugene.Zelenko added a subscriber: Eugene.Zelenko.

Committed in rL198582.