From d0072617b79f76189e5a9192aed1d2cf9fd21390 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 15 Aug 2024 15:30:10 -0700 Subject: [PATCH 1/2] [DAGCombiner] Don't let scalarizeBinOpOfSplats create illegal scalar MULHS/MULHU Type legalization lacks generic support for these operations. They are normally only created when the type is legal. This scalarization case is new. We could update type legalization, but there some corner cases that make it not straightforward. For example, if the promoted type isn't 2x the narrow type we need to over promote. Fixes #104480 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 + llvm/test/CodeGen/RISCV/rvv/pr104480.ll | 93 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 llvm/test/CodeGen/RISCV/rvv/pr104480.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 25644c24855a6..cab7be9dd4ddd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -27140,6 +27140,11 @@ static SDValue scalarizeBinOpOfSplats(SDNode *N, SelectionDAG &DAG, : TLI.getTypeToTransformTo(*DAG.getContext(), EltVT))) return SDValue(); + // FIXME: Type legalization can't handle illegal MULHS/MULHU. + if ((Opcode == ISD::MULHS || Opcode == ISD::MULHU) && + !TLI.isTypeLegal(EltVT)) + return SDValue(); + SDValue IndexC = DAG.getVectorIdxConstant(Index0, DL); SDValue X = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Src0, IndexC); SDValue Y = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, EltVT, Src1, IndexC); diff --git a/llvm/test/CodeGen/RISCV/rvv/pr104480.ll b/llvm/test/CodeGen/RISCV/rvv/pr104480.ll new file mode 100644 index 0000000000000..93cf4d3766089 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/pr104480.ll @@ -0,0 +1,93 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+v | FileCheck %s + +define @test_mulhs_promote( %broadcast.splatinsert, %0, %1) { +; CHECK-LABEL: test_mulhs_promote: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 0 +; CHECK-NEXT: lui a0, 5 +; CHECK-NEXT: addi a0, a0, 1366 +; CHECK-NEXT: vmulh.vx v8, v9, a0 +; CHECK-NEXT: vsrl.vi v10, v8, 15 +; CHECK-NEXT: vadd.vv v8, v8, v10 +; CHECK-NEXT: li a0, 3 +; CHECK-NEXT: vnmsub.vx v8, a0, v9 +; CHECK-NEXT: ret +entry: + %broadcast.splat = shufflevector %broadcast.splatinsert, zeroinitializer, zeroinitializer + %2 = srem %broadcast.splat, shufflevector ( insertelement ( poison, i16 3, i64 0), poison, zeroinitializer) + ret %2 +} + +define @test_mulhu_promote( %broadcast.splatinsert, %0, %1) { +; CHECK-LABEL: test_mulhu_promote: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli a0, zero, e16, m1, ta, ma +; CHECK-NEXT: vrgather.vi v9, v8, 0 +; CHECK-NEXT: lui a0, 1048571 +; CHECK-NEXT: addi a0, a0, -1365 +; CHECK-NEXT: vmulhu.vx v8, v9, a0 +; CHECK-NEXT: vsrl.vi v8, v8, 1 +; CHECK-NEXT: li a0, 3 +; CHECK-NEXT: vnmsub.vx v8, a0, v9 +; CHECK-NEXT: ret +entry: + %broadcast.splat = shufflevector %broadcast.splatinsert, zeroinitializer, zeroinitializer + %2 = urem %broadcast.splat, shufflevector ( insertelement ( poison, i16 3, i64 0), poison, zeroinitializer) + ret %2 +} + +define @test_mulhs_expand( %broadcast.splatinsert, %0, %1) { +; CHECK-LABEL: test_mulhs_expand: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi sp, sp, -16 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: lui a0, 349525 +; CHECK-NEXT: addi a1, a0, 1365 +; CHECK-NEXT: sw a1, 12(sp) +; CHECK-NEXT: addi a0, a0, 1366 +; CHECK-NEXT: sw a0, 8(sp) +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetvli a1, zero, e64, m4, ta, ma +; CHECK-NEXT: vlse64.v v12, (a0), zero +; CHECK-NEXT: vrgather.vi v16, v8, 0 +; CHECK-NEXT: vmulh.vv v8, v16, v12 +; CHECK-NEXT: li a0, 63 +; CHECK-NEXT: vsrl.vx v12, v8, a0 +; CHECK-NEXT: vadd.vv v8, v8, v12 +; CHECK-NEXT: li a0, 3 +; CHECK-NEXT: vnmsub.vx v8, a0, v16 +; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: ret +entry: + %broadcast.splat = shufflevector %broadcast.splatinsert, zeroinitializer, zeroinitializer + %2 = srem %broadcast.splat, shufflevector ( insertelement ( poison, i64 3, i64 0), poison, zeroinitializer) + ret %2 +} + +define @test_mulhu_expand( %broadcast.splatinsert, %0, %1) { +; CHECK-LABEL: test_mulhu_expand: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: addi sp, sp, -16 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: lui a0, 699051 +; CHECK-NEXT: addi a1, a0, -1366 +; CHECK-NEXT: sw a1, 12(sp) +; CHECK-NEXT: addi a0, a0, -1365 +; CHECK-NEXT: sw a0, 8(sp) +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetvli a1, zero, e64, m4, ta, ma +; CHECK-NEXT: vlse64.v v12, (a0), zero +; CHECK-NEXT: vrgather.vi v16, v8, 0 +; CHECK-NEXT: vmulhu.vv v8, v16, v12 +; CHECK-NEXT: vsrl.vi v8, v8, 1 +; CHECK-NEXT: li a0, 3 +; CHECK-NEXT: vnmsub.vx v8, a0, v16 +; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: ret +entry: + %broadcast.splat = shufflevector %broadcast.splatinsert, zeroinitializer, zeroinitializer + %2 = urem %broadcast.splat, shufflevector ( insertelement ( poison, i64 3, i64 0), poison, zeroinitializer) + ret %2 +} From 5a90ab42584b0bcfd5d5089b6fc3d782d91555ae Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Thu, 15 Aug 2024 15:56:21 -0700 Subject: [PATCH 2/2] fixup! clang-format --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index cab7be9dd4ddd..b21bea649e956 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -27141,8 +27141,7 @@ static SDValue scalarizeBinOpOfSplats(SDNode *N, SelectionDAG &DAG, return SDValue(); // FIXME: Type legalization can't handle illegal MULHS/MULHU. - if ((Opcode == ISD::MULHS || Opcode == ISD::MULHU) && - !TLI.isTypeLegal(EltVT)) + if ((Opcode == ISD::MULHS || Opcode == ISD::MULHU) && !TLI.isTypeLegal(EltVT)) return SDValue(); SDValue IndexC = DAG.getVectorIdxConstant(Index0, DL);