@@ -774,6 +774,7 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
774
774
ISD::UINT_TO_FP,
775
775
ISD::STRICT_FP_EXTEND,
776
776
ISD::BSWAP,
777
+ ISD::SETCC,
777
778
ISD::SDIV,
778
779
ISD::UDIV,
779
780
ISD::SREM,
@@ -3260,6 +3261,43 @@ static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL,
3260
3261
return ;
3261
3262
if (C.Op0 .getValueType () != MVT::i128 )
3262
3263
return ;
3264
+
3265
+ // Recognize vector comparison reductions.
3266
+ if ((C.CCMask == SystemZ::CCMASK_CMP_EQ ||
3267
+ C.CCMask == SystemZ::CCMASK_CMP_NE) &&
3268
+ (isNullConstant (C.Op1 ) || isAllOnesConstant (C.Op1 ))) {
3269
+ bool CmpEq = C.CCMask == SystemZ::CCMASK_CMP_EQ;
3270
+ bool CmpNull = isNullConstant (C.Op1 );
3271
+ SDValue Src = peekThroughBitcasts (C.Op0 );
3272
+ if (Src.hasOneUse () && isBitwiseNot (Src)) {
3273
+ Src = Src.getOperand (0 );
3274
+ CmpNull = !CmpNull;
3275
+ }
3276
+ unsigned Opcode = 0 ;
3277
+ if (Src.hasOneUse ()) {
3278
+ switch (Src.getOpcode ()) {
3279
+ case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES; break ;
3280
+ case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS; break ;
3281
+ case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS; break ;
3282
+ case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES; break ;
3283
+ case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS; break ;
3284
+ case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES; break ;
3285
+ default : break ;
3286
+ }
3287
+ }
3288
+ if (Opcode) {
3289
+ C.Opcode = Opcode;
3290
+ C.Op0 = Src->getOperand (0 );
3291
+ C.Op1 = Src->getOperand (1 );
3292
+ C.CCValid = SystemZ::CCMASK_VCMP;
3293
+ C.CCMask = CmpNull ? SystemZ::CCMASK_VCMP_NONE : SystemZ::CCMASK_VCMP_ALL;
3294
+ if (!CmpEq)
3295
+ C.CCMask ^= C.CCValid ;
3296
+ return ;
3297
+ }
3298
+ }
3299
+
3300
+ // Everything below here is not useful if we have native i128 compares.
3263
3301
if (DAG.getSubtarget <SystemZSubtarget>().hasVectorEnhancements3 ())
3264
3302
return ;
3265
3303
@@ -3443,8 +3481,14 @@ static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C) {
3443
3481
return DAG.getNode (SystemZISD::TM, DL, MVT::i32 , C.Op0 , C.Op1 ,
3444
3482
DAG.getTargetConstant (RegisterOnly, DL, MVT::i32 ));
3445
3483
}
3446
- if (C.Opcode == SystemZISD::VICMPES) {
3447
- SDVTList VTs = DAG.getVTList (C.Op0 .getValueType (), MVT::i32 );
3484
+ if (C.Opcode == SystemZISD::VICMPES ||
3485
+ C.Opcode == SystemZISD::VICMPHS ||
3486
+ C.Opcode == SystemZISD::VICMPHLS ||
3487
+ C.Opcode == SystemZISD::VFCMPES ||
3488
+ C.Opcode == SystemZISD::VFCMPHS ||
3489
+ C.Opcode == SystemZISD::VFCMPHES) {
3490
+ EVT IntVT = C.Op0 .getValueType ().changeVectorElementTypeToInteger ();
3491
+ SDVTList VTs = DAG.getVTList (IntVT, MVT::i32 );
3448
3492
SDValue Val = DAG.getNode (C.Opcode , DL, VTs, C.Op0 , C.Op1 );
3449
3493
return SDValue (Val.getNode (), 1 );
3450
3494
}
@@ -8036,6 +8080,42 @@ SDValue SystemZTargetLowering::combineBSWAP(
8036
8080
return SDValue ();
8037
8081
}
8038
8082
8083
+ SDValue SystemZTargetLowering::combineSETCC (
8084
+ SDNode *N, DAGCombinerInfo &DCI) const {
8085
+ SelectionDAG &DAG = DCI.DAG ;
8086
+ const ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand (2 ))->get ();
8087
+ const SDValue LHS = N->getOperand (0 );
8088
+ const SDValue RHS = N->getOperand (1 );
8089
+ bool CmpNull = isNullConstant (RHS);
8090
+ bool CmpAllOnes = isAllOnesConstant (RHS);
8091
+ EVT VT = N->getValueType (0 );
8092
+ SDLoc DL (N);
8093
+
8094
+ // Match icmp_eq/ne(bitcast(icmp(X,Y)),0/-1) reduction patterns, and
8095
+ // change the outer compare to a i128 compare. This will normally
8096
+ // allow the reduction to be recognized in adjustICmp128, and even if
8097
+ // not, the i128 compare will still generate better code.
8098
+ if ((CC == ISD::SETNE || CC == ISD::SETEQ) && (CmpNull || CmpAllOnes)) {
8099
+ SDValue Src = peekThroughBitcasts (LHS);
8100
+ if (Src.getOpcode () == ISD::SETCC &&
8101
+ Src.getValueType ().isFixedLengthVector () &&
8102
+ Src.getValueType ().getScalarType () == MVT::i1) {
8103
+ EVT CmpVT = Src.getOperand (0 ).getValueType ();
8104
+ if (CmpVT.getSizeInBits () == 128 ) {
8105
+ EVT IntVT = CmpVT.changeVectorElementTypeToInteger ();
8106
+ SDValue LHS =
8107
+ DAG.getBitcast (MVT::i128 , DAG.getSExtOrTrunc (Src, DL, IntVT));
8108
+ SDValue RHS = CmpNull ? DAG.getConstant (0 , DL, MVT::i128 )
8109
+ : DAG.getAllOnesConstant (DL, MVT::i128 );
8110
+ return DAG.getNode (ISD::SETCC, DL, VT, LHS, RHS, N->getOperand (2 ),
8111
+ N->getFlags ());
8112
+ }
8113
+ }
8114
+ }
8115
+
8116
+ return SDValue ();
8117
+ }
8118
+
8039
8119
static bool combineCCMask (SDValue &CCReg, int &CCValid, int &CCMask) {
8040
8120
// We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
8041
8121
// set by the CCReg instruction using the CCValid / CCMask masks,
@@ -8286,6 +8366,7 @@ SDValue SystemZTargetLowering::PerformDAGCombine(SDNode *N,
8286
8366
case ISD::SINT_TO_FP:
8287
8367
case ISD::UINT_TO_FP: return combineINT_TO_FP (N, DCI);
8288
8368
case ISD::BSWAP: return combineBSWAP (N, DCI);
8369
+ case ISD::SETCC: return combineSETCC (N, DCI);
8289
8370
case SystemZISD::BR_CCMASK: return combineBR_CCMASK (N, DCI);
8290
8371
case SystemZISD::SELECT_CCMASK: return combineSELECT_CCMASK (N, DCI);
8291
8372
case SystemZISD::GET_CCMASK: return combineGET_CCMASK (N, DCI);
0 commit comments