mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
SelectionDAG: create correct BooleanContent constants
Occasionally DAGCombiner can spot that a SETCC operation is completely redundant and reduce it to "all true" or "all false". If this happens to a vector, the value produced has to take account of what a normal comparison would have produced, which may be an all-1s bitmask. The fix in SelectionDAG.cpp is tested, however, as far as I can see the code in TargetLowering.cpp is possibly unreachable and almost certainly irrelevant when triggered so there are no tests. However, I believe it's still clearly the right change and may save someone else some hassle if it suddenly becomes reachable. So I'm doing it anyway. llvm-svn: 190147
This commit is contained in:
parent
d9577fe859
commit
5e921518f7
@ -1554,7 +1554,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1,
|
||||
case ISD::SETFALSE:
|
||||
case ISD::SETFALSE2: return getConstant(0, VT);
|
||||
case ISD::SETTRUE:
|
||||
case ISD::SETTRUE2: return getConstant(1, VT);
|
||||
case ISD::SETTRUE2: {
|
||||
const TargetLowering *TLI = TM.getTargetLowering();
|
||||
TargetLowering::BooleanContent Cnt = TLI->getBooleanContents(VT.isVector());
|
||||
return getConstant(
|
||||
Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, VT);
|
||||
}
|
||||
|
||||
case ISD::SETOEQ:
|
||||
case ISD::SETOGT:
|
||||
|
@ -1080,7 +1080,11 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
||||
case ISD::SETFALSE:
|
||||
case ISD::SETFALSE2: return DAG.getConstant(0, VT);
|
||||
case ISD::SETTRUE:
|
||||
case ISD::SETTRUE2: return DAG.getConstant(1, VT);
|
||||
case ISD::SETTRUE2: {
|
||||
TargetLowering::BooleanContent Cnt = getBooleanContents(VT.isVector());
|
||||
return DAG.getConstant(
|
||||
Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, VT);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the constant occurs on the RHS, and fold constant
|
||||
|
@ -124,3 +124,64 @@ define <4 x i32> @v4i32_icmp_ule(<4 x i32> %a, <4 x i32> %b) nounwind readnone s
|
||||
; AVX: pcmpeqd %xmm1, %xmm0, %xmm0
|
||||
}
|
||||
|
||||
; At one point we were incorrectly constant-folding a setcc to 0x1 instead of
|
||||
; 0xff, leading to a constpool load. The instruction doesn't matter here, but it
|
||||
; should set all bits to 1.
|
||||
define <16 x i8> @test_setcc_constfold_vi8(<16 x i8> %l, <16 x i8> %r) {
|
||||
%test1 = icmp eq <16 x i8> %l, %r
|
||||
%mask1 = sext <16 x i1> %test1 to <16 x i8>
|
||||
|
||||
%test2 = icmp ne <16 x i8> %l, %r
|
||||
%mask2 = sext <16 x i1> %test2 to <16 x i8>
|
||||
|
||||
%res = or <16 x i8> %mask1, %mask2
|
||||
ret <16 x i8> %res
|
||||
; SSE2-LABEL: test_setcc_constfold_vi8:
|
||||
; SSE2: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; SSE41-LABEL: test_setcc_constfold_vi8:
|
||||
; SSE41: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; AVX-LABEL: test_setcc_constfold_vi8:
|
||||
; AVX: vpcmpeqd %xmm0, %xmm0, %xmm0
|
||||
}
|
||||
|
||||
; Make sure sensible results come from doing extension afterwards
|
||||
define <16 x i8> @test_setcc_constfold_vi1(<16 x i8> %l, <16 x i8> %r) {
|
||||
%test1 = icmp eq <16 x i8> %l, %r
|
||||
%test2 = icmp ne <16 x i8> %l, %r
|
||||
|
||||
%res = or <16 x i1> %test1, %test2
|
||||
%mask = sext <16 x i1> %res to <16 x i8>
|
||||
ret <16 x i8> %mask
|
||||
; SSE2-LABEL: test_setcc_constfold_vi1:
|
||||
; SSE2: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; SSE41-LABEL: test_setcc_constfold_vi1:
|
||||
; SSE41: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; AVX-LABEL: test_setcc_constfold_vi1:
|
||||
; AVX: vpcmpeqd %xmm0, %xmm0, %xmm0
|
||||
}
|
||||
|
||||
|
||||
; 64-bit case is also particularly important, as the constant "-1" is probably
|
||||
; just 32-bits wide.
|
||||
define <2 x i64> @test_setcc_constfold_vi64(<2 x i64> %l, <2 x i64> %r) {
|
||||
%test1 = icmp eq <2 x i64> %l, %r
|
||||
%mask1 = sext <2 x i1> %test1 to <2 x i64>
|
||||
|
||||
%test2 = icmp ne <2 x i64> %l, %r
|
||||
%mask2 = sext <2 x i1> %test2 to <2 x i64>
|
||||
|
||||
%res = or <2 x i64> %mask1, %mask2
|
||||
ret <2 x i64> %res
|
||||
; SSE2-LABEL: test_setcc_constfold_vi64:
|
||||
; SSE2: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; SSE41-LABEL: test_setcc_constfold_vi64:
|
||||
; SSE41: pcmpeqd %xmm0, %xmm0
|
||||
|
||||
; AVX-LABEL: test_setcc_constfold_vi64:
|
||||
; AVX: vpcmpeqd %xmm0, %xmm0, %xmm0
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user