diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 1183f562c274d..b698ef4fcf0cc 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -6345,7 +6345,6 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDNode *N, SDValue Op0 = N->getOperand(0); SDValue Op1 = N->getOperand(1); EVT VT = N->getValueType(0); - EVT SVT = VT.getScalarType(); EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout()); EVT ShSVT = ShVT.getScalarType(); @@ -6355,6 +6354,8 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDNode *N, auto BuildSDIVPattern = [&](ConstantSDNode *C) { if (C->isZero()) return false; + + EVT CT = C->getValueType(0); APInt Divisor = C->getAPIntValue(); unsigned Shift = Divisor.countr_zero(); if (Shift) { @@ -6363,12 +6364,13 @@ static SDValue BuildExactSDIV(const TargetLowering &TLI, SDNode *N, } APInt Factor = Divisor.multiplicativeInverse(); Shifts.push_back(DAG.getConstant(Shift, dl, ShSVT)); - Factors.push_back(DAG.getConstant(Factor, dl, SVT)); + Factors.push_back(DAG.getConstant(Factor, dl, CT)); return true; }; // Collect all magic values from the build vector. - if (!ISD::matchUnaryPredicate(Op1, BuildSDIVPattern)) + if (!ISD::matchUnaryPredicate(Op1, BuildSDIVPattern, /*AllowUndefs=*/false, + /*AllowTruncation=*/true)) return SDValue(); SDValue Shift, Factor; diff --git a/llvm/test/CodeGen/AArch64/sdiv-by-const-promoted-ops.ll b/llvm/test/CodeGen/AArch64/sdiv-by-const-promoted-ops.ll index 053cbc0616454..840501ec48e42 100644 --- a/llvm/test/CodeGen/AArch64/sdiv-by-const-promoted-ops.ll +++ b/llvm/test/CodeGen/AArch64/sdiv-by-const-promoted-ops.ll @@ -75,3 +75,24 @@ define <16 x i16> @srem_v16i16_by_7(<16 x i16> %x) { %rem = srem <16 x i16> %x, ret <16 x i16> %rem } + +define <8 x i16> @sdiv_exact_v8i16_by_255(<8 x i16> %x) { +; CHECK-LABEL: sdiv_exact_v8i16_by_255: +; CHECK: // %bb.0: +; CHECK-NEXT: mvni v1.8h, #1, lsl #8 +; CHECK-NEXT: mul v0.8h, v0.8h, v1.8h +; CHECK-NEXT: ret + %div = sdiv exact <8 x i16> %x, splat (i16 255) + ret <8 x i16> %div +} + +define <16 x i16> @sdiv_exact_v16i16_by_255(<16 x i16> %x) { +; CHECK-LABEL: sdiv_exact_v16i16_by_255: +; CHECK: // %bb.0: +; CHECK-NEXT: mvni v2.8h, #1, lsl #8 +; CHECK-NEXT: mul v0.8h, v0.8h, v2.8h +; CHECK-NEXT: mul v1.8h, v1.8h, v2.8h +; CHECK-NEXT: ret + %div = sdiv exact <16 x i16> %x, splat (i16 255) + ret <16 x i16> %div +}