diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 5377f22e5c61f..6af90f1242fe8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5589,7 +5589,8 @@ SDValue DAGCombiner::visitMULHU(SDNode *N) { return DAG.getConstant(0, DL, VT); // fold (mulhu x, (1 << c)) -> x >> (bitwidth - c) - if (isConstantOrConstantVector(N1, /*NoOpaques*/ true) && + if (isConstantOrConstantVector(N1, /*NoOpaques=*/true, + /*AllowTruncation=*/true) && hasOperation(ISD::SRL, VT)) { if (SDValue LogBase2 = BuildLogBase2(N1, DL)) { unsigned NumEltBits = VT.getScalarSizeInBits(); @@ -29833,7 +29834,8 @@ static SDValue takeInexpensiveLog2(SelectionDAG &DAG, const SDLoc &DL, EVT VT, return false; }; - if (ISD::matchUnaryPredicate(Op, IsPowerOfTwo)) { + if (ISD::matchUnaryPredicate(Op, IsPowerOfTwo, /*AllowUndefs=*/false, + /*AllowTruncation=*/true)) { if (!VT.isVector()) return DAG.getConstant(Pow2Constants.back().logBase2(), DL, VT); // We need to create a build vector diff --git a/llvm/test/CodeGen/AArch64/mulhu-srl-promoted-ops.ll b/llvm/test/CodeGen/AArch64/mulhu-srl-promoted-ops.ll new file mode 100644 index 0000000000000..46f994bfba9a2 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/mulhu-srl-promoted-ops.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=aarch64-none-linux-gnu < %s | FileCheck %s + +define <8 x i16> @mulhu_v8i16_by_256(<8 x i16> %x) { +; CHECK-LABEL: mulhu_v8i16_by_256: +; CHECK: // %bb.0: +; CHECK-NEXT: ushr v0.8h, v0.8h, #8 +; CHECK-NEXT: ret + %x32 = zext <8 x i16> %x to <8 x i32> + %mul = mul <8 x i32> %x32, splat (i32 256) + %result = lshr <8 x i32> %mul, splat (i32 16) + %trunc = trunc <8 x i32> %result to <8 x i16> + ret <8 x i16> %trunc +} + +define <16 x i16> @mulhu_v16i16_by_256(<16 x i16> %x) { +; CHECK-LABEL: mulhu_v16i16_by_256: +; CHECK: // %bb.0: +; CHECK-NEXT: ushr v0.8h, v0.8h, #8 +; CHECK-NEXT: ushr v1.8h, v1.8h, #8 +; CHECK-NEXT: ret + %x32 = zext <16 x i16> %x to <16 x i32> + %mul = mul <16 x i32> %x32, splat (i32 256) + %result = lshr <16 x i32> %mul, splat (i32 16) + %trunc = trunc <16 x i32> %result to <16 x i16> + ret <16 x i16> %trunc +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vmulhu-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vmulhu-sdnode.ll index 3fd7f5be860cf..c0c9b1797f91f 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vmulhu-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vmulhu-sdnode.ll @@ -48,18 +48,11 @@ define @vmulhu_vi_nxv1i32_0( %va) { } define @vmulhu_vi_nxv1i32_1( %va) { -; RV32-LABEL: vmulhu_vi_nxv1i32_1: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a0, zero, e32, mf2, ta, ma -; RV32-NEXT: vsrl.vi v8, v8, 28 -; RV32-NEXT: ret -; -; RV64-LABEL: vmulhu_vi_nxv1i32_1: -; RV64: # %bb.0: -; RV64-NEXT: li a0, 16 -; RV64-NEXT: vsetvli a1, zero, e32, mf2, ta, ma -; RV64-NEXT: vmulhu.vx v8, v8, a0 -; RV64-NEXT: ret +; CHECK-LABEL: vmulhu_vi_nxv1i32_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, ma +; CHECK-NEXT: vsrl.vi v8, v8, 28 +; CHECK-NEXT: ret %vb = zext splat (i32 16) to %vc = zext %va to %vd = mul %vb, %vc @@ -114,18 +107,11 @@ define @vmulhu_vi_nxv2i32_0( %va) { } define @vmulhu_vi_nxv2i32_1( %va) { -; RV32-LABEL: vmulhu_vi_nxv2i32_1: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a0, zero, e32, m1, ta, ma -; RV32-NEXT: vsrl.vi v8, v8, 28 -; RV32-NEXT: ret -; -; RV64-LABEL: vmulhu_vi_nxv2i32_1: -; RV64: # %bb.0: -; RV64-NEXT: li a0, 16 -; RV64-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; RV64-NEXT: vmulhu.vx v8, v8, a0 -; RV64-NEXT: ret +; CHECK-LABEL: vmulhu_vi_nxv2i32_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma +; CHECK-NEXT: vsrl.vi v8, v8, 28 +; CHECK-NEXT: ret %vb = zext splat (i32 16) to %vc = zext %va to %vd = mul %vb, %vc @@ -180,18 +166,11 @@ define @vmulhu_vi_nxv4i32_0( %va) { } define @vmulhu_vi_nxv4i32_1( %va) { -; RV32-LABEL: vmulhu_vi_nxv4i32_1: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a0, zero, e32, m2, ta, ma -; RV32-NEXT: vsrl.vi v8, v8, 28 -; RV32-NEXT: ret -; -; RV64-LABEL: vmulhu_vi_nxv4i32_1: -; RV64: # %bb.0: -; RV64-NEXT: li a0, 16 -; RV64-NEXT: vsetvli a1, zero, e32, m2, ta, ma -; RV64-NEXT: vmulhu.vx v8, v8, a0 -; RV64-NEXT: ret +; CHECK-LABEL: vmulhu_vi_nxv4i32_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma +; CHECK-NEXT: vsrl.vi v8, v8, 28 +; CHECK-NEXT: ret %vb = zext splat (i32 16) to %vc = zext %va to %vd = mul %vb, %vc @@ -246,18 +225,11 @@ define @vmulhu_vi_nxv8i32_0( %va) { } define @vmulhu_vi_nxv8i32_1( %va) { -; RV32-LABEL: vmulhu_vi_nxv8i32_1: -; RV32: # %bb.0: -; RV32-NEXT: vsetvli a0, zero, e32, m4, ta, ma -; RV32-NEXT: vsrl.vi v8, v8, 28 -; RV32-NEXT: ret -; -; RV64-LABEL: vmulhu_vi_nxv8i32_1: -; RV64: # %bb.0: -; RV64-NEXT: li a0, 16 -; RV64-NEXT: vsetvli a1, zero, e32, m4, ta, ma -; RV64-NEXT: vmulhu.vx v8, v8, a0 -; RV64-NEXT: ret +; CHECK-LABEL: vmulhu_vi_nxv8i32_1: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma +; CHECK-NEXT: vsrl.vi v8, v8, 28 +; CHECK-NEXT: ret %vb = zext splat (i32 16) to %vc = zext %va to %vd = mul %vb, %vc @@ -265,3 +237,6 @@ define @vmulhu_vi_nxv8i32_1( %va) { %vf = trunc %ve to ret %vf } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; RV32: {{.*}} +; RV64: {{.*}}