From 92f7a6b5898f3686a7e45b5a6129d560b07da6c2 Mon Sep 17 00:00:00 2001 From: Piotr Fusik Date: Mon, 17 Mar 2025 16:14:23 +0100 Subject: [PATCH] [RISCV] Sink NOT to be fold into ANDN/ORN/XNOR/VANDN Undoes a negation being hoisted out of a loop, so that it can be fold into an inverted bitwise operation in the loop. Implements #108840 on RISC-V --- .../Target/RISCV/RISCVTargetTransformInfo.cpp | 33 ++ llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll | 318 ++++++++++++------ llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll | 288 ++++++++++------ llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll | 299 ++++++++++------ 4 files changed, 627 insertions(+), 311 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp index 11a658758a9cb..1060093043278 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp @@ -2779,6 +2779,39 @@ bool RISCVTTIImpl::isProfitableToSinkOperands( Instruction *I, SmallVectorImpl &Ops) const { using namespace llvm::PatternMatch; + if (I->isBitwiseLogicOp()) { + if (!I->getType()->isVectorTy()) { + if (ST->hasStdExtZbb() || ST->hasStdExtZbkb()) { + for (auto &Op : I->operands()) { + // (and/or/xor X, (not Y)) -> (andn/orn/xnor X, Y) + if (match(Op.get(), m_Not(m_Value()))) { + Ops.push_back(&Op); + return true; + } + } + } + } else if (I->getOpcode() == Instruction::And && ST->hasStdExtZvkb()) { + for (auto &Op : I->operands()) { + // (and X, (not Y)) -> (vandn.vv X, Y) + if (match(Op.get(), m_Not(m_Value()))) { + Ops.push_back(&Op); + return true; + } + // (and X, (splat (not Y))) -> (vandn.vx X, Y) + if (match(Op.get(), m_Shuffle(m_InsertElt(m_Value(), m_Not(m_Value()), + m_ZeroInt()), + m_Value(), m_ZeroMask()))) { + Use &InsertElt = cast(Op)->getOperandUse(0); + Use &Not = cast(InsertElt)->getOperandUse(1); + Ops.push_back(&Not); + Ops.push_back(&InsertElt); + Ops.push_back(&Op); + return true; + } + } + } + } + if (!I->getType()->isVectorTy() || !ST->hasVInstructions()) return false; diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll index a319156f8d1b8..88bb19f499ab5 100644 --- a/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll +++ b/llvm/test/CodeGen/RISCV/rv32zbb-zbkb.ll @@ -440,14 +440,22 @@ define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind { } define i32 @and_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB24_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a1, a0 -; CHECK-NEXT: .LBB24_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: and_hoisted_not_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB24_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: .LBB24_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: and_hoisted_not_i32: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB24_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV32ZBB-ZBKB-NEXT: .LBB24_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -460,14 +468,22 @@ identity: } define i32 @and_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB25_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a0, a1 -; CHECK-NEXT: .LBB25_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: and_hoisted_not_i32_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB25_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: .LBB25_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: and_hoisted_not_i32_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB25_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV32ZBB-ZBKB-NEXT: .LBB25_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -480,16 +496,25 @@ identity: } define i64 @and_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB26_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: and a1, a3, a1 -; CHECK-NEXT: .LBB26_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: and_hoisted_not_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB26_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: and a1, a3, a1 +; RV32I-NEXT: .LBB26_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: and_hoisted_not_i64: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB26_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2 +; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3 +; RV32ZBB-ZBKB-NEXT: .LBB26_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -502,16 +527,25 @@ identity: } define i64 @and_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB27_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: and a1, a1, a3 -; CHECK-NEXT: .LBB27_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: and_hoisted_not_i64_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB27_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: and a1, a1, a3 +; RV32I-NEXT: .LBB27_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: and_hoisted_not_i64_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB27_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: andn a0, a0, a2 +; RV32ZBB-ZBKB-NEXT: andn a1, a1, a3 +; RV32ZBB-ZBKB-NEXT: .LBB27_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -524,14 +558,22 @@ identity: } define i32 @or_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB28_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a1, a0 -; CHECK-NEXT: .LBB28_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: or_hoisted_not_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB28_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: .LBB28_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: or_hoisted_not_i32: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB28_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV32ZBB-ZBKB-NEXT: .LBB28_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -544,14 +586,22 @@ identity: } define i32 @or_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB29_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a0, a1 -; CHECK-NEXT: .LBB29_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: or_hoisted_not_i32_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB29_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: .LBB29_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: or_hoisted_not_i32_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB29_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV32ZBB-ZBKB-NEXT: .LBB29_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -564,16 +614,25 @@ identity: } define i64 @or_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB30_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: or a0, a2, a0 -; CHECK-NEXT: or a1, a3, a1 -; CHECK-NEXT: .LBB30_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: or_hoisted_not_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB30_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: or a0, a2, a0 +; RV32I-NEXT: or a1, a3, a1 +; RV32I-NEXT: .LBB30_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: or_hoisted_not_i64: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB30_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: orn a0, a0, a2 +; RV32ZBB-ZBKB-NEXT: orn a1, a1, a3 +; RV32ZBB-ZBKB-NEXT: .LBB30_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -586,16 +645,25 @@ identity: } define i64 @or_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB31_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: or a0, a0, a2 -; CHECK-NEXT: or a1, a1, a3 -; CHECK-NEXT: .LBB31_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: or_hoisted_not_i64_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB31_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: or a0, a0, a2 +; RV32I-NEXT: or a1, a1, a3 +; RV32I-NEXT: .LBB31_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: or_hoisted_not_i64_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB31_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: orn a0, a0, a2 +; RV32ZBB-ZBKB-NEXT: orn a1, a1, a3 +; RV32ZBB-ZBKB-NEXT: .LBB31_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -608,14 +676,22 @@ identity: } define i32 @xor_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB32_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: .LBB32_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: xor_hoisted_not_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB32_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: .LBB32_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: xor_hoisted_not_i32: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB32_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV32ZBB-ZBKB-NEXT: .LBB32_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -628,14 +704,22 @@ identity: } define i32 @xor_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB33_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: .LBB33_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: xor_hoisted_not_i32_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a2, .LBB33_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a1, a1 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: .LBB33_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: xor_hoisted_not_i32_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a2, .LBB33_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV32ZBB-ZBKB-NEXT: .LBB33_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -648,16 +732,25 @@ identity: } define i64 @xor_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB34_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: xor a0, a2, a0 -; CHECK-NEXT: xor a1, a3, a1 -; CHECK-NEXT: .LBB34_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: xor_hoisted_not_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB34_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: xor a0, a2, a0 +; RV32I-NEXT: xor a1, a3, a1 +; RV32I-NEXT: .LBB34_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: xor_hoisted_not_i64: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB34_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: xnor a0, a2, a0 +; RV32ZBB-ZBKB-NEXT: xnor a1, a3, a1 +; RV32ZBB-ZBKB-NEXT: .LBB34_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -670,16 +763,25 @@ identity: } define i64 @xor_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a4, .LBB35_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a3, a3 -; CHECK-NEXT: not a2, a2 -; CHECK-NEXT: xor a0, a0, a2 -; CHECK-NEXT: xor a1, a1, a3 -; CHECK-NEXT: .LBB35_2: # %identity -; CHECK-NEXT: ret +; RV32I-LABEL: xor_hoisted_not_i64_swapped: +; RV32I: # %bb.0: +; RV32I-NEXT: beqz a4, .LBB35_2 +; RV32I-NEXT: # %bb.1: # %mask +; RV32I-NEXT: not a3, a3 +; RV32I-NEXT: not a2, a2 +; RV32I-NEXT: xor a0, a0, a2 +; RV32I-NEXT: xor a1, a1, a3 +; RV32I-NEXT: .LBB35_2: # %identity +; RV32I-NEXT: ret +; +; RV32ZBB-ZBKB-LABEL: xor_hoisted_not_i64_swapped: +; RV32ZBB-ZBKB: # %bb.0: +; RV32ZBB-ZBKB-NEXT: beqz a4, .LBB35_2 +; RV32ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV32ZBB-ZBKB-NEXT: xnor a0, a2, a0 +; RV32ZBB-ZBKB-NEXT: xnor a1, a3, a1 +; RV32ZBB-ZBKB-NEXT: .LBB35_2: # %identity +; RV32ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll index 23b2c2d70a37a..4ca637b788a45 100644 --- a/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbkb.ll @@ -556,14 +556,22 @@ define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind { } define i32 @and_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB32_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a1, a0 -; CHECK-NEXT: .LBB32_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: and_hoisted_not_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB32_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: .LBB32_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i32: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB32_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB32_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -576,14 +584,22 @@ identity: } define i32 @and_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB33_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a0, a1 -; CHECK-NEXT: .LBB33_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: and_hoisted_not_i32_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB33_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: .LBB33_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i32_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB33_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB33_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -596,14 +612,22 @@ identity: } define i64 @and_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB34_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a1, a0 -; CHECK-NEXT: .LBB34_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: and_hoisted_not_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB34_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: .LBB34_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i64: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB34_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB34_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -616,14 +640,22 @@ identity: } define i64 @and_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: and_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB35_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: and a0, a0, a1 -; CHECK-NEXT: .LBB35_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: and_hoisted_not_i64_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB35_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: .LBB35_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: and_hoisted_not_i64_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB35_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: andn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB35_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -636,14 +668,22 @@ identity: } define i32 @or_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB36_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a1, a0 -; CHECK-NEXT: .LBB36_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: or_hoisted_not_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB36_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: .LBB36_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i32: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB36_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB36_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -656,14 +696,22 @@ identity: } define i32 @or_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB37_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a0, a1 -; CHECK-NEXT: .LBB37_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: or_hoisted_not_i32_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB37_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: .LBB37_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i32_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB37_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB37_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -676,14 +724,22 @@ identity: } define i64 @or_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB38_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a1, a0 -; CHECK-NEXT: .LBB38_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: or_hoisted_not_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB38_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: .LBB38_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i64: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB38_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB38_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -696,14 +752,22 @@ identity: } define i64 @or_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: or_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB39_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: or a0, a0, a1 -; CHECK-NEXT: .LBB39_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: or_hoisted_not_i64_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB39_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: .LBB39_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: or_hoisted_not_i64_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB39_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: orn a0, a0, a1 +; RV64ZBB-ZBKB-NEXT: .LBB39_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -716,14 +780,22 @@ identity: } define i32 @xor_hoisted_not_i32(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i32: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB40_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: .LBB40_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: xor_hoisted_not_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB40_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: .LBB40_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i32: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB40_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV64ZBB-ZBKB-NEXT: .LBB40_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -736,14 +808,22 @@ identity: } define i32 @xor_hoisted_not_i32_swapped(i32 %x, i32 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i32_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB41_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: .LBB41_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: xor_hoisted_not_i32_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB41_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: .LBB41_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i32_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB41_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV64ZBB-ZBKB-NEXT: .LBB41_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i32 %m, -1 br i1 %cond, label %mask, label %identity @@ -756,14 +836,22 @@ identity: } define i64 @xor_hoisted_not_i64(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i64: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB42_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: .LBB42_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: xor_hoisted_not_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB42_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: .LBB42_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i64: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB42_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV64ZBB-ZBKB-NEXT: .LBB42_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity @@ -776,14 +864,22 @@ identity: } define i64 @xor_hoisted_not_i64_swapped(i64 %x, i64 %m, i1 zeroext %cond) { -; CHECK-LABEL: xor_hoisted_not_i64_swapped: -; CHECK: # %bb.0: -; CHECK-NEXT: beqz a2, .LBB43_2 -; CHECK-NEXT: # %bb.1: # %mask -; CHECK-NEXT: not a1, a1 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: .LBB43_2: # %identity -; CHECK-NEXT: ret +; RV64I-LABEL: xor_hoisted_not_i64_swapped: +; RV64I: # %bb.0: +; RV64I-NEXT: beqz a2, .LBB43_2 +; RV64I-NEXT: # %bb.1: # %mask +; RV64I-NEXT: not a1, a1 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: .LBB43_2: # %identity +; RV64I-NEXT: ret +; +; RV64ZBB-ZBKB-LABEL: xor_hoisted_not_i64_swapped: +; RV64ZBB-ZBKB: # %bb.0: +; RV64ZBB-ZBKB-NEXT: beqz a2, .LBB43_2 +; RV64ZBB-ZBKB-NEXT: # %bb.1: # %mask +; RV64ZBB-ZBKB-NEXT: xnor a0, a1, a0 +; RV64ZBB-ZBKB-NEXT: .LBB43_2: # %identity +; RV64ZBB-ZBKB-NEXT: ret %a = xor i64 %m, -1 br i1 %cond, label %mask, label %identity diff --git a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll index 96eead1c191f7..a4c64d6fa5ef5 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vandn-sdnode.ll @@ -2125,9 +2125,8 @@ define @vand_vx_hoisted_not( %x, i8 %m, i1 ze ; CHECK-ZVKB: # %bb.0: ; CHECK-ZVKB-NEXT: beqz a1, .LBB94_2 ; CHECK-ZVKB-NEXT: # %bb.1: # %mask -; CHECK-ZVKB-NEXT: not a0, a0 ; CHECK-ZVKB-NEXT: vsetvli a1, zero, e8, mf8, ta, ma -; CHECK-ZVKB-NEXT: vand.vx v8, v8, a0 +; CHECK-ZVKB-NEXT: vandn.vx v8, v8, a0 ; CHECK-ZVKB-NEXT: .LBB94_2: # %identity ; CHECK-ZVKB-NEXT: ret %a = xor i8 %m, -1 @@ -2158,9 +2157,8 @@ define @vand_vx_hoisted_not_swapped( %x, i8 % ; CHECK-ZVKB: # %bb.0: ; CHECK-ZVKB-NEXT: beqz a1, .LBB95_2 ; CHECK-ZVKB-NEXT: # %bb.1: # %mask -; CHECK-ZVKB-NEXT: not a0, a0 ; CHECK-ZVKB-NEXT: vsetvli a1, zero, e8, mf8, ta, ma -; CHECK-ZVKB-NEXT: vand.vx v8, v8, a0 +; CHECK-ZVKB-NEXT: vandn.vx v8, v8, a0 ; CHECK-ZVKB-NEXT: .LBB95_2: # %identity ; CHECK-ZVKB-NEXT: ret %a = xor i8 %m, -1 @@ -2192,8 +2190,7 @@ define @vand_vv_hoisted_not( %x, %m, splat (i8 -1) @@ -2223,8 +2220,7 @@ define @vand_vv_hoisted_not_swapped( %x, %m, splat (i8 -1) @@ -2336,100 +2332,194 @@ define void @vand_vx_loop_hoisted_not(ptr %a, i32 noundef signext %mask) { ; CHECK-RV64-NEXT: .LBB98_7: # %for.cond.cleanup ; CHECK-RV64-NEXT: ret ; -; CHECK-ZVKB32-LABEL: vand_vx_loop_hoisted_not: -; CHECK-ZVKB32: # %bb.0: # %entry -; CHECK-ZVKB32-NEXT: csrr a4, vlenb -; CHECK-ZVKB32-NEXT: srli a3, a4, 3 -; CHECK-ZVKB32-NEXT: li a2, 64 -; CHECK-ZVKB32-NEXT: not a1, a1 -; CHECK-ZVKB32-NEXT: bgeu a2, a3, .LBB98_2 -; CHECK-ZVKB32-NEXT: # %bb.1: -; CHECK-ZVKB32-NEXT: li a3, 0 -; CHECK-ZVKB32-NEXT: li a2, 0 -; CHECK-ZVKB32-NEXT: j .LBB98_5 -; CHECK-ZVKB32-NEXT: .LBB98_2: # %vector.ph -; CHECK-ZVKB32-NEXT: li a2, 0 -; CHECK-ZVKB32-NEXT: slli a3, a3, 2 -; CHECK-ZVKB32-NEXT: neg a3, a3 -; CHECK-ZVKB32-NEXT: andi a3, a3, 256 -; CHECK-ZVKB32-NEXT: srli a4, a4, 1 -; CHECK-ZVKB32-NEXT: li a6, 0 -; CHECK-ZVKB32-NEXT: li a5, 0 -; CHECK-ZVKB32-NEXT: vsetvli a7, zero, e32, m2, ta, ma -; CHECK-ZVKB32-NEXT: .LBB98_3: # %vector.body -; CHECK-ZVKB32-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-ZVKB32-NEXT: slli a7, a6, 2 -; CHECK-ZVKB32-NEXT: add t0, a6, a4 -; CHECK-ZVKB32-NEXT: add a7, a0, a7 -; CHECK-ZVKB32-NEXT: vl2re32.v v8, (a7) -; CHECK-ZVKB32-NEXT: sltu a6, t0, a6 -; CHECK-ZVKB32-NEXT: add a5, a5, a6 -; CHECK-ZVKB32-NEXT: xor a6, t0, a3 -; CHECK-ZVKB32-NEXT: vand.vx v8, v8, a1 -; CHECK-ZVKB32-NEXT: or t1, a6, a5 -; CHECK-ZVKB32-NEXT: vs2r.v v8, (a7) -; CHECK-ZVKB32-NEXT: mv a6, t0 -; CHECK-ZVKB32-NEXT: bnez t1, .LBB98_3 -; CHECK-ZVKB32-NEXT: # %bb.4: # %middle.block -; CHECK-ZVKB32-NEXT: bnez a3, .LBB98_6 -; CHECK-ZVKB32-NEXT: .LBB98_5: # %for.body -; CHECK-ZVKB32-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-ZVKB32-NEXT: slli a4, a3, 2 -; CHECK-ZVKB32-NEXT: addi a3, a3, 1 -; CHECK-ZVKB32-NEXT: add a4, a0, a4 -; CHECK-ZVKB32-NEXT: lw a5, 0(a4) -; CHECK-ZVKB32-NEXT: seqz a6, a3 -; CHECK-ZVKB32-NEXT: add a2, a2, a6 -; CHECK-ZVKB32-NEXT: xori a6, a3, 256 -; CHECK-ZVKB32-NEXT: and a5, a5, a1 -; CHECK-ZVKB32-NEXT: or a6, a6, a2 -; CHECK-ZVKB32-NEXT: sw a5, 0(a4) -; CHECK-ZVKB32-NEXT: bnez a6, .LBB98_5 -; CHECK-ZVKB32-NEXT: .LBB98_6: # %for.cond.cleanup -; CHECK-ZVKB32-NEXT: ret -; -; CHECK-ZVKB64-LABEL: vand_vx_loop_hoisted_not: -; CHECK-ZVKB64: # %bb.0: # %entry -; CHECK-ZVKB64-NEXT: csrr a4, vlenb -; CHECK-ZVKB64-NEXT: srli a2, a4, 3 -; CHECK-ZVKB64-NEXT: li a3, 64 -; CHECK-ZVKB64-NEXT: not a1, a1 -; CHECK-ZVKB64-NEXT: bgeu a3, a2, .LBB98_2 -; CHECK-ZVKB64-NEXT: # %bb.1: -; CHECK-ZVKB64-NEXT: li a2, 0 -; CHECK-ZVKB64-NEXT: j .LBB98_5 -; CHECK-ZVKB64-NEXT: .LBB98_2: # %vector.ph -; CHECK-ZVKB64-NEXT: slli a2, a2, 2 -; CHECK-ZVKB64-NEXT: negw a2, a2 -; CHECK-ZVKB64-NEXT: andi a2, a2, 256 -; CHECK-ZVKB64-NEXT: srli a3, a4, 1 -; CHECK-ZVKB64-NEXT: slli a4, a4, 1 -; CHECK-ZVKB64-NEXT: mv a5, a0 -; CHECK-ZVKB64-NEXT: mv a6, a2 -; CHECK-ZVKB64-NEXT: vsetvli a7, zero, e32, m2, ta, ma -; CHECK-ZVKB64-NEXT: .LBB98_3: # %vector.body -; CHECK-ZVKB64-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-ZVKB64-NEXT: vl2re32.v v8, (a5) -; CHECK-ZVKB64-NEXT: sub a6, a6, a3 -; CHECK-ZVKB64-NEXT: vand.vx v8, v8, a1 -; CHECK-ZVKB64-NEXT: vs2r.v v8, (a5) -; CHECK-ZVKB64-NEXT: add a5, a5, a4 -; CHECK-ZVKB64-NEXT: bnez a6, .LBB98_3 -; CHECK-ZVKB64-NEXT: # %bb.4: # %middle.block -; CHECK-ZVKB64-NEXT: bnez a2, .LBB98_7 -; CHECK-ZVKB64-NEXT: .LBB98_5: # %for.body.preheader -; CHECK-ZVKB64-NEXT: slli a2, a2, 2 -; CHECK-ZVKB64-NEXT: add a2, a0, a2 -; CHECK-ZVKB64-NEXT: addi a0, a0, 1024 -; CHECK-ZVKB64-NEXT: .LBB98_6: # %for.body -; CHECK-ZVKB64-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-ZVKB64-NEXT: lw a3, 0(a2) -; CHECK-ZVKB64-NEXT: and a3, a3, a1 -; CHECK-ZVKB64-NEXT: sw a3, 0(a2) -; CHECK-ZVKB64-NEXT: addi a2, a2, 4 -; CHECK-ZVKB64-NEXT: bne a2, a0, .LBB98_6 -; CHECK-ZVKB64-NEXT: .LBB98_7: # %for.cond.cleanup -; CHECK-ZVKB64-NEXT: ret +; CHECK-ZVKB-NOZBB32-LABEL: vand_vx_loop_hoisted_not: +; CHECK-ZVKB-NOZBB32: # %bb.0: # %entry +; CHECK-ZVKB-NOZBB32-NEXT: csrr a4, vlenb +; CHECK-ZVKB-NOZBB32-NEXT: srli a3, a4, 3 +; CHECK-ZVKB-NOZBB32-NEXT: li a2, 64 +; CHECK-ZVKB-NOZBB32-NEXT: bgeu a2, a3, .LBB98_2 +; CHECK-ZVKB-NOZBB32-NEXT: # %bb.1: +; CHECK-ZVKB-NOZBB32-NEXT: li a3, 0 +; CHECK-ZVKB-NOZBB32-NEXT: li a2, 0 +; CHECK-ZVKB-NOZBB32-NEXT: j .LBB98_5 +; CHECK-ZVKB-NOZBB32-NEXT: .LBB98_2: # %vector.ph +; CHECK-ZVKB-NOZBB32-NEXT: li a2, 0 +; CHECK-ZVKB-NOZBB32-NEXT: slli a3, a3, 2 +; CHECK-ZVKB-NOZBB32-NEXT: neg a3, a3 +; CHECK-ZVKB-NOZBB32-NEXT: andi a3, a3, 256 +; CHECK-ZVKB-NOZBB32-NEXT: srli a4, a4, 1 +; CHECK-ZVKB-NOZBB32-NEXT: li a6, 0 +; CHECK-ZVKB-NOZBB32-NEXT: li a5, 0 +; CHECK-ZVKB-NOZBB32-NEXT: vsetvli a7, zero, e32, m2, ta, ma +; CHECK-ZVKB-NOZBB32-NEXT: .LBB98_3: # %vector.body +; CHECK-ZVKB-NOZBB32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-NOZBB32-NEXT: slli a7, a6, 2 +; CHECK-ZVKB-NOZBB32-NEXT: add t0, a6, a4 +; CHECK-ZVKB-NOZBB32-NEXT: add a7, a0, a7 +; CHECK-ZVKB-NOZBB32-NEXT: vl2re32.v v8, (a7) +; CHECK-ZVKB-NOZBB32-NEXT: sltu a6, t0, a6 +; CHECK-ZVKB-NOZBB32-NEXT: add a5, a5, a6 +; CHECK-ZVKB-NOZBB32-NEXT: xor a6, t0, a3 +; CHECK-ZVKB-NOZBB32-NEXT: vandn.vx v8, v8, a1 +; CHECK-ZVKB-NOZBB32-NEXT: or t1, a6, a5 +; CHECK-ZVKB-NOZBB32-NEXT: vs2r.v v8, (a7) +; CHECK-ZVKB-NOZBB32-NEXT: mv a6, t0 +; CHECK-ZVKB-NOZBB32-NEXT: bnez t1, .LBB98_3 +; CHECK-ZVKB-NOZBB32-NEXT: # %bb.4: # %middle.block +; CHECK-ZVKB-NOZBB32-NEXT: bnez a3, .LBB98_7 +; CHECK-ZVKB-NOZBB32-NEXT: .LBB98_5: # %for.body.preheader +; CHECK-ZVKB-NOZBB32-NEXT: not a1, a1 +; CHECK-ZVKB-NOZBB32-NEXT: .LBB98_6: # %for.body +; CHECK-ZVKB-NOZBB32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-NOZBB32-NEXT: slli a4, a3, 2 +; CHECK-ZVKB-NOZBB32-NEXT: addi a3, a3, 1 +; CHECK-ZVKB-NOZBB32-NEXT: add a4, a0, a4 +; CHECK-ZVKB-NOZBB32-NEXT: lw a5, 0(a4) +; CHECK-ZVKB-NOZBB32-NEXT: seqz a6, a3 +; CHECK-ZVKB-NOZBB32-NEXT: add a2, a2, a6 +; CHECK-ZVKB-NOZBB32-NEXT: xori a6, a3, 256 +; CHECK-ZVKB-NOZBB32-NEXT: and a5, a5, a1 +; CHECK-ZVKB-NOZBB32-NEXT: or a6, a6, a2 +; CHECK-ZVKB-NOZBB32-NEXT: sw a5, 0(a4) +; CHECK-ZVKB-NOZBB32-NEXT: bnez a6, .LBB98_6 +; CHECK-ZVKB-NOZBB32-NEXT: .LBB98_7: # %for.cond.cleanup +; CHECK-ZVKB-NOZBB32-NEXT: ret +; +; CHECK-ZVKB-NOZBB64-LABEL: vand_vx_loop_hoisted_not: +; CHECK-ZVKB-NOZBB64: # %bb.0: # %entry +; CHECK-ZVKB-NOZBB64-NEXT: csrr a4, vlenb +; CHECK-ZVKB-NOZBB64-NEXT: srli a2, a4, 3 +; CHECK-ZVKB-NOZBB64-NEXT: li a3, 64 +; CHECK-ZVKB-NOZBB64-NEXT: bgeu a3, a2, .LBB98_2 +; CHECK-ZVKB-NOZBB64-NEXT: # %bb.1: +; CHECK-ZVKB-NOZBB64-NEXT: li a2, 0 +; CHECK-ZVKB-NOZBB64-NEXT: j .LBB98_5 +; CHECK-ZVKB-NOZBB64-NEXT: .LBB98_2: # %vector.ph +; CHECK-ZVKB-NOZBB64-NEXT: slli a2, a2, 2 +; CHECK-ZVKB-NOZBB64-NEXT: negw a2, a2 +; CHECK-ZVKB-NOZBB64-NEXT: andi a2, a2, 256 +; CHECK-ZVKB-NOZBB64-NEXT: srli a3, a4, 1 +; CHECK-ZVKB-NOZBB64-NEXT: slli a4, a4, 1 +; CHECK-ZVKB-NOZBB64-NEXT: mv a5, a0 +; CHECK-ZVKB-NOZBB64-NEXT: mv a6, a2 +; CHECK-ZVKB-NOZBB64-NEXT: vsetvli a7, zero, e32, m2, ta, ma +; CHECK-ZVKB-NOZBB64-NEXT: .LBB98_3: # %vector.body +; CHECK-ZVKB-NOZBB64-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-NOZBB64-NEXT: vl2re32.v v8, (a5) +; CHECK-ZVKB-NOZBB64-NEXT: sub a6, a6, a3 +; CHECK-ZVKB-NOZBB64-NEXT: vandn.vx v8, v8, a1 +; CHECK-ZVKB-NOZBB64-NEXT: vs2r.v v8, (a5) +; CHECK-ZVKB-NOZBB64-NEXT: add a5, a5, a4 +; CHECK-ZVKB-NOZBB64-NEXT: bnez a6, .LBB98_3 +; CHECK-ZVKB-NOZBB64-NEXT: # %bb.4: # %middle.block +; CHECK-ZVKB-NOZBB64-NEXT: bnez a2, .LBB98_7 +; CHECK-ZVKB-NOZBB64-NEXT: .LBB98_5: # %for.body.preheader +; CHECK-ZVKB-NOZBB64-NEXT: not a1, a1 +; CHECK-ZVKB-NOZBB64-NEXT: slli a2, a2, 2 +; CHECK-ZVKB-NOZBB64-NEXT: add a2, a0, a2 +; CHECK-ZVKB-NOZBB64-NEXT: addi a0, a0, 1024 +; CHECK-ZVKB-NOZBB64-NEXT: .LBB98_6: # %for.body +; CHECK-ZVKB-NOZBB64-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-NOZBB64-NEXT: lw a3, 0(a2) +; CHECK-ZVKB-NOZBB64-NEXT: and a3, a3, a1 +; CHECK-ZVKB-NOZBB64-NEXT: sw a3, 0(a2) +; CHECK-ZVKB-NOZBB64-NEXT: addi a2, a2, 4 +; CHECK-ZVKB-NOZBB64-NEXT: bne a2, a0, .LBB98_6 +; CHECK-ZVKB-NOZBB64-NEXT: .LBB98_7: # %for.cond.cleanup +; CHECK-ZVKB-NOZBB64-NEXT: ret +; +; CHECK-ZVKB-ZBB32-LABEL: vand_vx_loop_hoisted_not: +; CHECK-ZVKB-ZBB32: # %bb.0: # %entry +; CHECK-ZVKB-ZBB32-NEXT: csrr a4, vlenb +; CHECK-ZVKB-ZBB32-NEXT: srli a3, a4, 3 +; CHECK-ZVKB-ZBB32-NEXT: li a2, 64 +; CHECK-ZVKB-ZBB32-NEXT: bgeu a2, a3, .LBB98_2 +; CHECK-ZVKB-ZBB32-NEXT: # %bb.1: +; CHECK-ZVKB-ZBB32-NEXT: li a3, 0 +; CHECK-ZVKB-ZBB32-NEXT: li a2, 0 +; CHECK-ZVKB-ZBB32-NEXT: j .LBB98_5 +; CHECK-ZVKB-ZBB32-NEXT: .LBB98_2: # %vector.ph +; CHECK-ZVKB-ZBB32-NEXT: li a2, 0 +; CHECK-ZVKB-ZBB32-NEXT: slli a3, a3, 2 +; CHECK-ZVKB-ZBB32-NEXT: neg a3, a3 +; CHECK-ZVKB-ZBB32-NEXT: andi a3, a3, 256 +; CHECK-ZVKB-ZBB32-NEXT: srli a4, a4, 1 +; CHECK-ZVKB-ZBB32-NEXT: li a6, 0 +; CHECK-ZVKB-ZBB32-NEXT: li a5, 0 +; CHECK-ZVKB-ZBB32-NEXT: vsetvli a7, zero, e32, m2, ta, ma +; CHECK-ZVKB-ZBB32-NEXT: .LBB98_3: # %vector.body +; CHECK-ZVKB-ZBB32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-ZBB32-NEXT: slli a7, a6, 2 +; CHECK-ZVKB-ZBB32-NEXT: add t0, a6, a4 +; CHECK-ZVKB-ZBB32-NEXT: add a7, a0, a7 +; CHECK-ZVKB-ZBB32-NEXT: vl2re32.v v8, (a7) +; CHECK-ZVKB-ZBB32-NEXT: sltu a6, t0, a6 +; CHECK-ZVKB-ZBB32-NEXT: add a5, a5, a6 +; CHECK-ZVKB-ZBB32-NEXT: xor a6, t0, a3 +; CHECK-ZVKB-ZBB32-NEXT: vandn.vx v8, v8, a1 +; CHECK-ZVKB-ZBB32-NEXT: or t1, a6, a5 +; CHECK-ZVKB-ZBB32-NEXT: vs2r.v v8, (a7) +; CHECK-ZVKB-ZBB32-NEXT: mv a6, t0 +; CHECK-ZVKB-ZBB32-NEXT: bnez t1, .LBB98_3 +; CHECK-ZVKB-ZBB32-NEXT: # %bb.4: # %middle.block +; CHECK-ZVKB-ZBB32-NEXT: bnez a3, .LBB98_6 +; CHECK-ZVKB-ZBB32-NEXT: .LBB98_5: # %for.body +; CHECK-ZVKB-ZBB32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-ZBB32-NEXT: slli a4, a3, 2 +; CHECK-ZVKB-ZBB32-NEXT: addi a3, a3, 1 +; CHECK-ZVKB-ZBB32-NEXT: add a4, a0, a4 +; CHECK-ZVKB-ZBB32-NEXT: lw a5, 0(a4) +; CHECK-ZVKB-ZBB32-NEXT: seqz a6, a3 +; CHECK-ZVKB-ZBB32-NEXT: add a2, a2, a6 +; CHECK-ZVKB-ZBB32-NEXT: xori a6, a3, 256 +; CHECK-ZVKB-ZBB32-NEXT: andn a5, a5, a1 +; CHECK-ZVKB-ZBB32-NEXT: or a6, a6, a2 +; CHECK-ZVKB-ZBB32-NEXT: sw a5, 0(a4) +; CHECK-ZVKB-ZBB32-NEXT: bnez a6, .LBB98_5 +; CHECK-ZVKB-ZBB32-NEXT: .LBB98_6: # %for.cond.cleanup +; CHECK-ZVKB-ZBB32-NEXT: ret +; +; CHECK-ZVKB-ZBB64-LABEL: vand_vx_loop_hoisted_not: +; CHECK-ZVKB-ZBB64: # %bb.0: # %entry +; CHECK-ZVKB-ZBB64-NEXT: csrr a4, vlenb +; CHECK-ZVKB-ZBB64-NEXT: srli a2, a4, 3 +; CHECK-ZVKB-ZBB64-NEXT: li a3, 64 +; CHECK-ZVKB-ZBB64-NEXT: bgeu a3, a2, .LBB98_2 +; CHECK-ZVKB-ZBB64-NEXT: # %bb.1: +; CHECK-ZVKB-ZBB64-NEXT: li a2, 0 +; CHECK-ZVKB-ZBB64-NEXT: j .LBB98_5 +; CHECK-ZVKB-ZBB64-NEXT: .LBB98_2: # %vector.ph +; CHECK-ZVKB-ZBB64-NEXT: slli a2, a2, 2 +; CHECK-ZVKB-ZBB64-NEXT: negw a2, a2 +; CHECK-ZVKB-ZBB64-NEXT: andi a2, a2, 256 +; CHECK-ZVKB-ZBB64-NEXT: srli a3, a4, 1 +; CHECK-ZVKB-ZBB64-NEXT: slli a4, a4, 1 +; CHECK-ZVKB-ZBB64-NEXT: mv a5, a0 +; CHECK-ZVKB-ZBB64-NEXT: mv a6, a2 +; CHECK-ZVKB-ZBB64-NEXT: vsetvli a7, zero, e32, m2, ta, ma +; CHECK-ZVKB-ZBB64-NEXT: .LBB98_3: # %vector.body +; CHECK-ZVKB-ZBB64-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-ZBB64-NEXT: vl2re32.v v8, (a5) +; CHECK-ZVKB-ZBB64-NEXT: sub a6, a6, a3 +; CHECK-ZVKB-ZBB64-NEXT: vandn.vx v8, v8, a1 +; CHECK-ZVKB-ZBB64-NEXT: vs2r.v v8, (a5) +; CHECK-ZVKB-ZBB64-NEXT: add a5, a5, a4 +; CHECK-ZVKB-ZBB64-NEXT: bnez a6, .LBB98_3 +; CHECK-ZVKB-ZBB64-NEXT: # %bb.4: # %middle.block +; CHECK-ZVKB-ZBB64-NEXT: bnez a2, .LBB98_7 +; CHECK-ZVKB-ZBB64-NEXT: .LBB98_5: # %for.body.preheader +; CHECK-ZVKB-ZBB64-NEXT: slli a2, a2, 2 +; CHECK-ZVKB-ZBB64-NEXT: add a2, a0, a2 +; CHECK-ZVKB-ZBB64-NEXT: addi a0, a0, 1024 +; CHECK-ZVKB-ZBB64-NEXT: .LBB98_6: # %for.body +; CHECK-ZVKB-ZBB64-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-ZVKB-ZBB64-NEXT: lw a3, 0(a2) +; CHECK-ZVKB-ZBB64-NEXT: andn a3, a3, a1 +; CHECK-ZVKB-ZBB64-NEXT: sw a3, 0(a2) +; CHECK-ZVKB-ZBB64-NEXT: addi a2, a2, 4 +; CHECK-ZVKB-ZBB64-NEXT: bne a2, a0, .LBB98_6 +; CHECK-ZVKB-ZBB64-NEXT: .LBB98_7: # %for.cond.cleanup +; CHECK-ZVKB-ZBB64-NEXT: ret entry: %not = xor i32 %mask, -1 %vscale = tail call i64 @llvm.vscale.i64() @@ -2477,8 +2567,3 @@ for.body: %exitcond.not = icmp eq i64 %indvars.iv.next, 256 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; CHECK-ZVKB-NOZBB32: {{.*}} -; CHECK-ZVKB-NOZBB64: {{.*}} -; CHECK-ZVKB-ZBB32: {{.*}} -; CHECK-ZVKB-ZBB64: {{.*}}