@@ -2073,8 +2073,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
20732073
20742074 if (Subtarget.hasVBMI2()) {
20752075 for (auto VT : {MVT::v32i16, MVT::v16i32, MVT::v8i64}) {
2076- setOperationAction(ISD::FSHL, VT, Custom );
2077- setOperationAction(ISD::FSHR, VT, Custom );
2076+ setOperationAction(ISD::FSHL, VT, Legal );
2077+ setOperationAction(ISD::FSHR, VT, Legal );
20782078 }
20792079
20802080 setOperationAction(ISD::ROTL, MVT::v32i16, Custom);
@@ -2089,8 +2089,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
20892089 if (!Subtarget.useSoftFloat() && Subtarget.hasVBMI2()) {
20902090 for (auto VT : {MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::v16i16, MVT::v8i32,
20912091 MVT::v4i64}) {
2092- setOperationAction(ISD::FSHL, VT, Custom);
2093- setOperationAction(ISD::FSHR, VT, Custom);
2092+ setOperationAction(ISD::FSHL, VT, Subtarget.hasVLX() ? Legal : Custom);
2093+ setOperationAction(ISD::FSHR, VT, Subtarget.hasVLX() ? Legal : Custom);
20942094 }
20952095 }
20962096
@@ -2703,6 +2703,8 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
27032703 ISD::STRICT_FP_EXTEND,
27042704 ISD::FP_ROUND,
27052705 ISD::STRICT_FP_ROUND,
2706+ ISD::FSHL,
2707+ ISD::FSHR,
27062708 ISD::INTRINSIC_VOID,
27072709 ISD::INTRINSIC_WO_CHAIN,
27082710 ISD::INTRINSIC_W_CHAIN});
@@ -57624,6 +57626,41 @@ static SDValue combineFP_TO_xINT_SAT(SDNode *N, SelectionDAG &DAG,
5762457626 return SDValue();
5762557627}
5762657628
57629+ // Combiner: turn uniform-constant splat funnel shifts into VSHLD/VSHRD
57630+ static SDValue combineFunnelShift(SDNode *N, SelectionDAG &DAG,
57631+ TargetLowering::DAGCombinerInfo &DCI,
57632+ const X86Subtarget &Subtarget) {
57633+ SDLoc DL(N);
57634+ SDValue Op0 = N->getOperand(0);
57635+ SDValue Op1 = N->getOperand(1);
57636+ SDValue Amt = N->getOperand(2);
57637+ EVT VT = Op0.getValueType();
57638+
57639+ if (!VT.isVector())
57640+ return SDValue();
57641+
57642+ // Only combine if the operation is legal for this type.
57643+ // This ensures we don't try to convert types that need to be
57644+ // widened/promoted.
57645+ if (!DAG.getTargetLoweringInfo().isOperationLegal(N->getOpcode(), VT))
57646+ return SDValue();
57647+
57648+ unsigned EltSize = VT.getScalarSizeInBits();
57649+ APInt ShiftVal;
57650+ if (!X86::isConstantSplat(Amt, ShiftVal))
57651+ return SDValue();
57652+
57653+ uint64_t ModAmt = ShiftVal.urem(EltSize);
57654+ SDValue Imm = DAG.getTargetConstant(ModAmt, DL, MVT::i8);
57655+ bool IsFSHR = N->getOpcode() == ISD::FSHR;
57656+
57657+ if (IsFSHR)
57658+ std::swap(Op0, Op1);
57659+ unsigned Opcode = IsFSHR ? X86ISD::VSHRD : X86ISD::VSHLD;
57660+
57661+ return DAG.getNode(Opcode, DL, VT, {Op0, Op1, Imm});
57662+ }
57663+
5762757664static bool needCarryOrOverflowFlag(SDValue Flags) {
5762857665 assert(Flags.getValueType() == MVT::i32 && "Unexpected VT!");
5762957666
@@ -61228,6 +61265,8 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
6122861265 case ISD::INTRINSIC_VOID: return combineINTRINSIC_VOID(N, DAG, DCI);
6122961266 case ISD::FP_TO_SINT_SAT:
6123061267 case ISD::FP_TO_UINT_SAT: return combineFP_TO_xINT_SAT(N, DAG, Subtarget);
61268+ case ISD::FSHL:
61269+ case ISD::FSHR: return combineFunnelShift(N, DAG, DCI, Subtarget);
6123161270 // clang-format on
6123261271 }
6123361272
0 commit comments