I try to legalize:
...
---
name: test_unmerge_192
body: |
bb.1:
%0:_(s192) = IMPLICIT_DEF
%1:_(s96), %2:_(s96) = G_UNMERGE_VALUES %0(s192)
%3:_(s96) = COPY %1(s96)
RET 0, implicit %3
It fails all the way from 32-bit to AVX2 X86.
// extract multiple registers
getActionDefinitionsBuilder(G_UNMERGE_VALUES)
.legalIf([=](const LegalityQuery &Query) -> bool {
if (typeInSet(0, {s16, s32, s64})(Query))
return true;
if (Is64Bit && typeInSet(0, {s128})(Query))
return true;
if (HasSSE1 && typeInSet(0, {v4s32, v2s64})(Query))
return true;
if (HasSSE2 && typeInSet(0, {v16s8, v32s8, v8s16, v16s16,
v4s32, v8s32, v2s64, v4s64})(Query))
return true;
if (HasAVX && typeInSet(0, {v32s8, v64s8, v16s16, v32s16,
v8s32, v16s32, v4s64, v8s64})(Query))
return true;
if (HasAVX2 && typeInSet(0, {v64s8, v32s16, v16s32, v8s64})(Query))
return true;
return false;
})
// elements (clamp and widen)
.clampScalarOrElt(0, s16, sMaxScalar)
.widenScalarOrEltToNextPow2(0, /*Min=*/16)
.clampScalarOrElt(1, s16, sMaxScalar)
.widenScalarOrEltToNextPow2(1, /*Min=*/16)
// vectors (min and max)
.clampMinNumElements(0, s16, bitWidth / 16)
.clampMinNumElements(0, s32, bitWidth / 32)
.clampMinNumElements(0, s64, bitWidth / 64)
.clampMaxNumElements(0, s16,
HasAVX2 ? 32 :
(HasAVX ? 16 :
bitWidth / 16))
.clampMaxNumElements(0, s32,
HasAVX2 ? 16 :
(HasAVX ? 8 :
bitWidth / 32))
.clampMaxNumElements(0, s64,
HasAVX2 ? 8 :
(HasAVX ? 4 :
bitWidth / 64))
// last resort
.scalarize(0)
.scalarize(1);
I am a bit worried that clampScalarOrElt
does not work as expected or I am completely misunderstanding legalization. Any ideas?
Thanks!