llvm.org GIT mirror llvm / a370ce2
Merging r228518: ------------------------------------------------------------------------ r228518 | tnorthover | 2015-02-07 16:50:47 -0800 (Sat, 07 Feb 2015) | 15 lines ARM & AArch64: teach LowerVSETCC that output type size may differ from input. While various DAG combines try to guarantee that a vector SETCC operation will have the same output size as input, there's nothing intrinsic to either creation or LegalizeTypes that actually guarantees it, so the function needs to be ready to handle a mismatch. Fortunately this is easy enough, just extend or truncate the naturally compared result. I couldn't reproduce the failure in other backends that I know have SIMD, so it's probably only an issue for these two due to shared heritage. Should fix PR21645. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@228560 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 5 years ago
4 changed file(s) with 51 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
62866286 AArch64CC::CondCode CC, bool NoNans, EVT VT,
62876287 SDLoc dl, SelectionDAG &DAG) {
62886288 EVT SrcVT = LHS.getValueType();
6289 assert(VT.getSizeInBits() == SrcVT.getSizeInBits() &&
6290 "function only supposed to emit natural comparisons");
62896291
62906292 BuildVectorSDNode *BVN = dyn_cast(RHS.getNode());
62916293 APInt CnstBits(VT.getSizeInBits(), 0);
63806382 ISD::CondCode CC = cast(Op.getOperand(2))->get();
63816383 SDValue LHS = Op.getOperand(0);
63826384 SDValue RHS = Op.getOperand(1);
6385 EVT CmpVT = LHS.getValueType().changeVectorElementTypeToInteger();
63836386 SDLoc dl(Op);
63846387
63856388 if (LHS.getValueType().getVectorElementType().isInteger()) {
63866389 assert(LHS.getValueType() == RHS.getValueType());
63876390 AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
6388 return EmitVectorComparison(LHS, RHS, AArch64CC, false, Op.getValueType(),
6389 dl, DAG);
6391 SDValue Cmp =
6392 EmitVectorComparison(LHS, RHS, AArch64CC, false, CmpVT, dl, DAG);
6393 return DAG.getSExtOrTrunc(Cmp, dl, Op.getValueType());
63906394 }
63916395
63926396 assert(LHS.getValueType().getVectorElementType() == MVT::f32 ||
64006404
64016405 bool NoNaNs = getTargetMachine().Options.NoNaNsFPMath;
64026406 SDValue Cmp =
6403 EmitVectorComparison(LHS, RHS, CC1, NoNaNs, Op.getValueType(), dl, DAG);
6407 EmitVectorComparison(LHS, RHS, CC1, NoNaNs, CmpVT, dl, DAG);
64046408 if (!Cmp.getNode())
64056409 return SDValue();
64066410
64076411 if (CC2 != AArch64CC::AL) {
64086412 SDValue Cmp2 =
6409 EmitVectorComparison(LHS, RHS, CC2, NoNaNs, Op.getValueType(), dl, DAG);
6413 EmitVectorComparison(LHS, RHS, CC2, NoNaNs, CmpVT, dl, DAG);
64106414 if (!Cmp2.getNode())
64116415 return SDValue();
64126416
6413 Cmp = DAG.getNode(ISD::OR, dl, Cmp.getValueType(), Cmp, Cmp2);
6414 }
6417 Cmp = DAG.getNode(ISD::OR, dl, CmpVT, Cmp, Cmp2);
6418 }
6419
6420 Cmp = DAG.getSExtOrTrunc(Cmp, dl, Op.getValueType());
64156421
64166422 if (ShouldInvert)
64176423 return Cmp = DAG.getNOT(dl, Cmp, Cmp.getValueType());
44864486 SDValue Op0 = Op.getOperand(0);
44874487 SDValue Op1 = Op.getOperand(1);
44884488 SDValue CC = Op.getOperand(2);
4489 EVT CmpVT = Op0.getValueType().changeVectorElementTypeToInteger();
44894490 EVT VT = Op.getValueType();
44904491 ISD::CondCode SetCCOpcode = cast(CC)->get();
44914492 SDLoc dl(Op);
45154516 TmpOp0 = Op0;
45164517 TmpOp1 = Op1;
45174518 Opc = ISD::OR;
4518 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0);
4519 Op1 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp0, TmpOp1);
4519 Op0 = DAG.getNode(ARMISD::VCGT, dl, CmpVT, TmpOp1, TmpOp0);
4520 Op1 = DAG.getNode(ARMISD::VCGT, dl, CmpVT, TmpOp0, TmpOp1);
45204521 break;
45214522 case ISD::SETUO: Invert = true; // Fallthrough
45224523 case ISD::SETO:
45244525 TmpOp0 = Op0;
45254526 TmpOp1 = Op1;
45264527 Opc = ISD::OR;
4527 Op0 = DAG.getNode(ARMISD::VCGT, dl, VT, TmpOp1, TmpOp0);
4528 Op1 = DAG.getNode(ARMISD::VCGE, dl, VT, TmpOp0, TmpOp1);
4528 Op0 = DAG.getNode(ARMISD::VCGT, dl, CmpVT, TmpOp1, TmpOp0);
4529 Op1 = DAG.getNode(ARMISD::VCGE, dl, CmpVT, TmpOp0, TmpOp1);
45294530 break;
45304531 }
45314532 } else {
45594560
45604561 if (AndOp.getNode() && AndOp.getOpcode() == ISD::AND) {
45614562 Opc = ARMISD::VTST;
4562 Op0 = DAG.getNode(ISD::BITCAST, dl, VT, AndOp.getOperand(0));
4563 Op1 = DAG.getNode(ISD::BITCAST, dl, VT, AndOp.getOperand(1));
4563 Op0 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(0));
4564 Op1 = DAG.getNode(ISD::BITCAST, dl, CmpVT, AndOp.getOperand(1));
45644565 Invert = !Invert;
45654566 }
45664567 }
45864587 if (SingleOp.getNode()) {
45874588 switch (Opc) {
45884589 case ARMISD::VCEQ:
4589 Result = DAG.getNode(ARMISD::VCEQZ, dl, VT, SingleOp); break;
4590 Result = DAG.getNode(ARMISD::VCEQZ, dl, CmpVT, SingleOp); break;
45904591 case ARMISD::VCGE:
4591 Result = DAG.getNode(ARMISD::VCGEZ, dl, VT, SingleOp); break;
4592 Result = DAG.getNode(ARMISD::VCGEZ, dl, CmpVT, SingleOp); break;
45924593 case ARMISD::VCLEZ:
4593 Result = DAG.getNode(ARMISD::VCLEZ, dl, VT, SingleOp); break;
4594 Result = DAG.getNode(ARMISD::VCLEZ, dl, CmpVT, SingleOp); break;
45944595 case ARMISD::VCGT:
4595 Result = DAG.getNode(ARMISD::VCGTZ, dl, VT, SingleOp); break;
4596 Result = DAG.getNode(ARMISD::VCGTZ, dl, CmpVT, SingleOp); break;
45964597 case ARMISD::VCLTZ:
4597 Result = DAG.getNode(ARMISD::VCLTZ, dl, VT, SingleOp); break;
4598 Result = DAG.getNode(ARMISD::VCLTZ, dl, CmpVT, SingleOp); break;
45984599 default:
4599 Result = DAG.getNode(Opc, dl, VT, Op0, Op1);
4600 Result = DAG.getNode(Opc, dl, CmpVT, Op0, Op1);
46004601 }
46014602 } else {
4602 Result = DAG.getNode(Opc, dl, VT, Op0, Op1);
4603 }
4603 Result = DAG.getNode(Opc, dl, CmpVT, Op0, Op1);
4604 }
4605
4606 Result = DAG.getSExtOrTrunc(Result, dl, VT);
46044607
46054608 if (Invert)
46064609 Result = DAG.getNOT(dl, Result, VT);
0 ; RUN: llc -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s
1
2 define void @test_mismatched_setcc(<4 x i22> %l, <4 x i22> %r, <4 x i1>* %addr) {
3 ; CHECK-LABEL: test_mismatched_setcc:
4 ; CHECK: cmeq [[CMP128:v[0-9]+]].4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
5 ; CHECK: xtn {{v[0-9]+}}.4h, [[CMP128]].4s
6
7 %tst = icmp eq <4 x i22> %l, %r
8 store <4 x i1> %tst, <4 x i1>* %addr
9 ret void
10 }
0 ; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s
1
2 define void @test_mismatched_setcc(<4 x i22> %l, <4 x i22> %r, <4 x i1>* %addr) {
3 ; CHECK-LABEL: test_mismatched_setcc:
4 ; CHECK: vceq.i32 [[CMP128:q[0-9]+]], {{q[0-9]+}}, {{q[0-9]+}}
5 ; CHECK: vmovn.i32 {{d[0-9]+}}, [[CMP128]]
6
7 %tst = icmp eq <4 x i22> %l, %r
8 store <4 x i1> %tst, <4 x i1>* %addr
9 ret void
10 }