[llvm-commits] [llvm] r162960 - in /llvm/trunk: lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp test/CodeGen/X86/vec_select.ll
Peter Cooper
peter_cooper at apple.com
Sat Sep 1 10:41:33 PDT 2012
Hi Duncan
Thanks for the detailed explanation! I've reverted this in r163064.
I can now see what you mean about handling this in the select. I need to move the code i have here to the legalization of vselect where it wasn't extending the boolean condition correctly if turning a vselect in to and, or, xor.
Thanks,
Pete
On Sep 1, 2012, at 9:35 AM, Duncan Sands <baldrick at free.fr> wrote:
> Hi Pete,
>
> On 31/08/12 01:58, Pete Cooper wrote:
>> Author: pete
>> Date: Thu Aug 30 18:58:52 2012
>> New Revision: 162960
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=162960&view=rev
>> Log:
>> Take account of boolean vector contents when promoting a build vector from i1 to some other type. rdar://problem/12210060
>
> unfortunately this is wrong, it should be in the "select" code. A general
> principle of type legalization is that extra bits are undefined, hold rubbish.
> Thus when turning an i1 value into an i8 value, or a <4 x i1> value into
> a <4 x i8> value (or whatever) then the upper 7 bits of each i8 value are
> undefined. Feeding such promoted values directly into some operations is
> fine, for other operations it is not. For example consider a sum of i1 values:
> x = add i1 y, z. If Y and Z are the corresponding i8 values (bit 0 of Y
> equals y, other bits might be anything, etc), then Y+Z has the same bit 0 as
> x, i.e. any rubbish in the upper bits of Y and Z has no effect on bit 0 of
> the sum, so Y+Z can be used as the promoted value for x. For other operations
> directly feeding the promoted values in is not OK, for example consider x =
> udiv y, z. You can't use udiv Y, Z as the promoted value for x. That's
> because value of the upper bits in Y and Z does impact bit 0 of udiv Y, Z.
> That's why when the legalization code visits a udiv, it first forms Y' and Z'
> by clearing the upper 7 bits of Y and Z to 0, and then forms X = udiv Y', Z'
> (which has the correct bit 0 so can be used as the promoted value for x).
>
> Select and setcc nodes are an example of operations of the second kind: you
> can't just take their i1 operand c and replace it with any value C with the
> same bit 0. You first need to form C' from C by zeroing off the top 7 bits,
> or sign extending bit 0 (depending on the machine), and then use C' for the
> new operand. Notice how the existing uses of getBooleanContents (which says
> which method to use) are all in legalization of (v)select or (v)setcc nodes.
>
> In short you shouldn't be trying to fix up bits in outputs (build_vector), you
> should be fixing them up on inputs (select/setcc).
>
> So can you please correct the patch.
>
> Best wishes, Duncan.
>
>>
>> Added:
>> llvm/trunk/test/CodeGen/X86/vec_select.ll
>> Modified:
>> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>>
>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=162960&r1=162959&r2=162960&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Thu Aug 30 18:58:52 2012
>> @@ -2913,8 +2913,24 @@
>>
>> SmallVector<SDValue, 8> Ops;
>> Ops.reserve(NumElems);
>> + unsigned ExtendOp = ISD::ANY_EXTEND;
>> + // Extending boolean constants needs to consider the
>> + // value boolean vector constants take on this target and extend
>> + // with sign or zeros appropriately.
>> + if (OutVT.getVectorElementType() == MVT::i1) {
>> + switch (TLI.getBooleanContents(true)) {
>> + case TargetLowering::UndefinedBooleanContent:
>> + break;
>> + case TargetLowering::ZeroOrOneBooleanContent:
>> + ExtendOp = ISD::ZERO_EXTEND;
>> + break;
>> + case TargetLowering::ZeroOrNegativeOneBooleanContent:
>> + ExtendOp = ISD::SIGN_EXTEND;
>> + break;
>> + }
>> + }
>> for (unsigned i = 0; i != NumElems; ++i) {
>> - SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(i));
>> + SDValue Op = DAG.getNode(ExtendOp, dl, NOutVTElem, N->getOperand(i));
>> Ops.push_back(Op);
>> }
>>
>>
>> Added: llvm/trunk/test/CodeGen/X86/vec_select.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_select.ll?rev=162960&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/CodeGen/X86/vec_select.ll (added)
>> +++ llvm/trunk/test/CodeGen/X86/vec_select.ll Thu Aug 30 18:58:52 2012
>> @@ -0,0 +1,16 @@
>> +; RUN: llc < %s -march=x86 | FileCheck %s
>> +
>> +; When legalizing the v4i1 constant, we need to consider the boolean contents
>> +; For x86 a boolean vector constant is all ones so the constants in memory
>> +; will be ~0U not 1.
>> +
>> +; CHECK: .long 4294967295
>> +; CHECK: .long 4294967295
>> +; CHECK: .long 0
>> +; CHECK: .long 0
>> +
>> +; CHECK: test
>> +define <4 x i8> @test(<4 x i8> %a, <4 x i8> %b) {
>> + %sel = select <4 x i1> <i1 true, i1 true, i1 false, i1 false>, <4 x i8> %a, <4 x i8> %b
>> + ret <4 x i8> %sel
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list