diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h --- a/llvm/lib/Target/RISCV/RISCVISelLowering.h +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -315,6 +315,7 @@ bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override; bool isCheapToSpeculateCttz() const override; bool isCheapToSpeculateCtlz() const override; + bool hasAndNot(SDValue Y) const override; bool shouldSinkOperands(Instruction *I, SmallVectorImpl &Ops) const override; bool isFPImmLegal(const APFloat &Imm, EVT VT, diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -1105,6 +1105,19 @@ return Subtarget.hasStdExtZbb(); } +bool RISCVTargetLowering::hasAndNot(SDValue Y) const { + EVT VT = Y.getValueType(); + + // FIXME: Support vectors once we have tests. + if (VT.isVector()) + return false; + + if (!Subtarget.hasStdExtZbb()) + return false; + + return !isa(Y); +} + /// Check if sinking \p I's operands to I's basic block is profitable, because /// the operands can be folded into a target instruction, e.g. /// splats of scalars can fold into vector instructions. diff --git a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll --- a/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll +++ b/llvm/test/CodeGen/RISCV/selectcc-to-shiftand.ll @@ -117,14 +117,35 @@ ; Compare if positive and select variable or zero. define i32 @pos_sel_variable_and_zero(i32 signext %a, i32 signext %b) { -; CHECK-LABEL: pos_sel_variable_and_zero: -; CHECK: # %bb.0: -; CHECK-NEXT: bgez a0, .LBB6_2 -; CHECK-NEXT: # %bb.1: -; CHECK-NEXT: mv a1, zero -; CHECK-NEXT: .LBB6_2: -; CHECK-NEXT: mv a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: pos_sel_variable_and_zero: +; RV32I: # %bb.0: +; RV32I-NEXT: bgez a0, .LBB6_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: .LBB6_2: +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: pos_sel_variable_and_zero: +; RV64I: # %bb.0: +; RV64I-NEXT: bgez a0, .LBB6_2 +; RV64I-NEXT: # %bb.1: +; RV64I-NEXT: mv a1, zero +; RV64I-NEXT: .LBB6_2: +; RV64I-NEXT: mv a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: pos_sel_variable_and_zero: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: srai a0, a0, 31 +; RV32ZBB-NEXT: andn a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: pos_sel_variable_and_zero: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: srai a0, a0, 31 +; RV64ZBB-NEXT: andn a0, a1, a0 +; RV64ZBB-NEXT: ret %tmp.1 = icmp sgt i32 %a, -1 %retval = select i1 %tmp.1, i32 %b, i32 0 ret i32 %retval diff --git a/llvm/test/CodeGen/RISCV/unfold-masked-merge-scalar-variablemask.ll b/llvm/test/CodeGen/RISCV/unfold-masked-merge-scalar-variablemask.ll --- a/llvm/test/CodeGen/RISCV/unfold-masked-merge-scalar-variablemask.ll +++ b/llvm/test/CodeGen/RISCV/unfold-masked-merge-scalar-variablemask.ll @@ -167,12 +167,33 @@ ; TODO: These tests should produce the same output as the corresponding out* test. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; define i8 @in8(i8 %x, i8 %y, i8 %mask) { -; CHECK-LABEL: in8: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in8: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in8: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in8: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in8: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i8 %x, %y %n1 = and i8 %n0, %mask %r = xor i8 %n1, %y @@ -180,12 +201,33 @@ } define i16 @in16(i16 %x, i16 %y, i16 %mask) { -; CHECK-LABEL: in16: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in16: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in16: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in16: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in16: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i16 %x, %y %n1 = and i16 %n0, %mask %r = xor i16 %n1, %y @@ -193,12 +235,33 @@ } define i32 @in32(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in32: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in32: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in32: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in32: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in32: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask %r = xor i32 %n1, %y @@ -206,22 +269,39 @@ } define i64 @in64(i64 %x, i64 %y, i64 %mask) { -; RV32-LABEL: in64: -; RV32: # %bb.0: -; RV32-NEXT: xor a0, a0, a2 -; RV32-NEXT: xor a1, a1, a3 -; RV32-NEXT: and a1, a1, a5 -; RV32-NEXT: and a0, a0, a4 -; RV32-NEXT: xor a0, a0, a2 -; RV32-NEXT: xor a1, a1, a3 -; RV32-NEXT: ret +; RV32I-LABEL: in64: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a2 +; RV32I-NEXT: xor a1, a1, a3 +; RV32I-NEXT: and a1, a1, a5 +; RV32I-NEXT: and a0, a0, a4 +; RV32I-NEXT: xor a0, a0, a2 +; RV32I-NEXT: xor a1, a1, a3 +; RV32I-NEXT: ret ; -; RV64-LABEL: in64: -; RV64: # %bb.0: -; RV64-NEXT: xor a0, a0, a1 -; RV64-NEXT: and a0, a0, a2 -; RV64-NEXT: xor a0, a0, a1 -; RV64-NEXT: ret +; RV64I-LABEL: in64: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in64: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a2, a2, a4 +; RV32ZBB-NEXT: and a0, a0, a4 +; RV32ZBB-NEXT: or a0, a0, a2 +; RV32ZBB-NEXT: andn a2, a3, a5 +; RV32ZBB-NEXT: and a1, a1, a5 +; RV32ZBB-NEXT: or a1, a1, a2 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in64: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i64 %x, %y %n1 = and i64 %n0, %mask %r = xor i64 %n1, %y @@ -232,12 +312,33 @@ ; Commutativity tests. ; ============================================================================ ; define i32 @in_commutativity_0_0_1(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_0_0_1: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_0_0_1: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_0_0_1: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a2, a0 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_0_0_1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_0_0_1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %mask, %n0 ; swapped %r = xor i32 %n1, %y @@ -245,12 +346,33 @@ } define i32 @in_commutativity_0_1_0(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_0_1_0: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_0_1_0: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_0_1_0: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_0_1_0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_0_1_0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask %r = xor i32 %y, %n1 ; swapped @@ -258,12 +380,33 @@ } define i32 @in_commutativity_0_1_1(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_0_1_1: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_0_1_1: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_0_1_1: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a2, a0 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_0_1_1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_0_1_1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %mask, %n0 ; swapped %r = xor i32 %y, %n1 ; swapped @@ -271,12 +414,33 @@ } define i32 @in_commutativity_1_0_0(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_1_0_0: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a1, a0, a1 -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_1_0_0: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a1, a0, a1 +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_1_0_0: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a1, a0, a1 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_1_0_0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a0, a2 +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: or a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_1_0_0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a0, a2 +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: or a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask %r = xor i32 %n1, %x ; %x instead of %y @@ -284,12 +448,33 @@ } define i32 @in_commutativity_1_0_1(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_1_0_1: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a1, a0, a1 -; CHECK-NEXT: and a1, a2, a1 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_1_0_1: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a1, a0, a1 +; RV32I-NEXT: and a1, a2, a1 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_1_0_1: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a1, a0, a1 +; RV64I-NEXT: and a1, a2, a1 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_1_0_1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a0, a2 +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: or a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_1_0_1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a0, a2 +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: or a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %mask, %n0 ; swapped %r = xor i32 %n1, %x ; %x instead of %y @@ -297,12 +482,33 @@ } define i32 @in_commutativity_1_1_0(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_1_1_0: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a1, a0, a1 -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_1_1_0: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a1, a0, a1 +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_1_1_0: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a1, a0, a1 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_1_1_0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a0, a2 +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: or a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_1_1_0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a0, a2 +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: or a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask %r = xor i32 %x, %n1 ; swapped, %x instead of %y @@ -310,12 +516,33 @@ } define i32 @in_commutativity_1_1_1(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_commutativity_1_1_1: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a1, a0, a1 -; CHECK-NEXT: and a1, a2, a1 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_commutativity_1_1_1: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a1, a0, a1 +; RV32I-NEXT: and a1, a2, a1 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_commutativity_1_1_1: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a1, a0, a1 +; RV64I-NEXT: and a1, a2, a1 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_commutativity_1_1_1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a0, a2 +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: or a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_commutativity_1_1_1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a0, a2 +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: or a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, %y %n1 = and i32 %mask, %n0 ; swapped %r = xor i32 %x, %n1 ; swapped, %x instead of %y @@ -326,13 +553,37 @@ ; Y is an 'and' too. ; ============================================================================ ; define i32 @in_complex_y0(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { -; CHECK-LABEL: in_complex_y0: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a3 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y0: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a3 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y0: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a3 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a3 +; RV32ZBB-NEXT: andn a1, a1, a3 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a3 +; RV64ZBB-NEXT: andn a1, a1, a3 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask @@ -341,13 +592,37 @@ } define i32 @in_complex_y1(i32 %x, i32 %y_hi, i32 %y_low, i32 %mask) { -; CHECK-LABEL: in_complex_y1: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a3 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y1: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a3 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y1: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a3 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a3 +; RV32ZBB-NEXT: andn a1, a1, a3 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a3 +; RV64ZBB-NEXT: andn a1, a1, a3 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask @@ -359,13 +634,37 @@ ; M is an 'xor' too. ; ============================================================================ ; define i32 @in_complex_m0(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_m0: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a2, a2, a3 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_m0: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a2, a2, a3 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_m0: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a2, a2, a3 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_m0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: xor a2, a2, a3 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_m0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: xor a2, a2, a3 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y %n1 = and i32 %n0, %mask @@ -374,13 +673,37 @@ } define i32 @in_complex_m1(i32 %x, i32 %y, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_m1: -; CHECK: # %bb.0: -; CHECK-NEXT: xor a2, a2, a3 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_m1: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a2, a2, a3 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_m1: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a2, a2, a3 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a2, a0 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_m1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: xor a2, a2, a3 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_m1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: xor a2, a2, a3 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y %n1 = and i32 %mask, %n0 @@ -392,14 +715,41 @@ ; Both Y and M are complex. ; ============================================================================ ; define i32 @in_complex_y0_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_y0_m0: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a2, a3, a4 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y0_m0: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a2, a3, a4 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y0_m0: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a2, a3, a4 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y0_m0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: xor a2, a3, a4 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y0_m0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: xor a2, a3, a4 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y @@ -409,14 +759,41 @@ } define i32 @in_complex_y1_m0(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_y1_m0: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a2, a3, a4 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y1_m0: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a2, a3, a4 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y1_m0: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a2, a3, a4 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y1_m0: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: xor a2, a3, a4 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y1_m0: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: xor a2, a3, a4 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y @@ -426,14 +803,41 @@ } define i32 @in_complex_y0_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_y0_m1: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a2, a3, a4 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y0_m1: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a2, a3, a4 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y0_m1: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a2, a3, a4 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a2, a0 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y0_m1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: xor a2, a3, a4 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y0_m1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: xor a2, a3, a4 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y @@ -443,14 +847,41 @@ } define i32 @in_complex_y1_m1(i32 %x, i32 %y_hi, i32 %y_low, i32 %m_a, i32 %m_b) { -; CHECK-LABEL: in_complex_y1_m1: -; CHECK: # %bb.0: -; CHECK-NEXT: and a1, a1, a2 -; CHECK-NEXT: xor a2, a3, a4 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: and a0, a2, a0 -; CHECK-NEXT: xor a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: in_complex_y1_m1: +; RV32I: # %bb.0: +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: xor a2, a3, a4 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: and a0, a2, a0 +; RV32I-NEXT: xor a0, a1, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_complex_y1_m1: +; RV64I: # %bb.0: +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: xor a2, a3, a4 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: and a0, a2, a0 +; RV64I-NEXT: xor a0, a1, a0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_complex_y1_m1: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: and a1, a1, a2 +; RV32ZBB-NEXT: xor a2, a3, a4 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: and a0, a0, a2 +; RV32ZBB-NEXT: or a0, a0, a1 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_complex_y1_m1: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: and a1, a1, a2 +; RV64ZBB-NEXT: xor a2, a3, a4 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: and a0, a0, a2 +; RV64ZBB-NEXT: or a0, a0, a1 +; RV64ZBB-NEXT: ret %y = and i32 %y_hi, %y_low %mask = xor i32 %m_a, %m_b %n0 = xor i32 %x, %y @@ -618,12 +1049,33 @@ } define i32 @in_constant_varx_42(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_constant_varx_42: -; CHECK: # %bb.0: -; CHECK-NEXT: xori a0, a0, 42 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xori a0, a0, 42 -; CHECK-NEXT: ret +; RV32I-LABEL: in_constant_varx_42: +; RV32I: # %bb.0: +; RV32I-NEXT: xori a0, a0, 42 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xori a0, a0, 42 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_constant_varx_42: +; RV64I: # %bb.0: +; RV64I-NEXT: xori a0, a0, 42 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xori a0, a0, 42 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_constant_varx_42: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a2, a0 +; RV32ZBB-NEXT: ori a1, a2, 42 +; RV32ZBB-NEXT: andn a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_constant_varx_42: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a2, a0 +; RV64ZBB-NEXT: ori a1, a2, 42 +; RV64ZBB-NEXT: andn a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 %x, 42 ; %x %n1 = and i32 %n0, %mask %r = xor i32 %n1, 42 @@ -688,16 +1140,16 @@ ; ; RV32ZBB-LABEL: in_constant_varx_42_invmask: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: xori a0, a0, 42 ; RV32ZBB-NEXT: andn a0, a0, a2 -; RV32ZBB-NEXT: xori a0, a0, 42 +; RV32ZBB-NEXT: andi a1, a2, 42 +; RV32ZBB-NEXT: or a0, a0, a1 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: in_constant_varx_42_invmask: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: xori a0, a0, 42 ; RV64ZBB-NEXT: andn a0, a0, a2 -; RV64ZBB-NEXT: xori a0, a0, 42 +; RV64ZBB-NEXT: andi a1, a2, 42 +; RV64ZBB-NEXT: or a0, a0, a1 ; RV64ZBB-NEXT: ret %notmask = xor i32 %mask, -1 %n0 = xor i32 %x, 42 ; %x @@ -860,12 +1312,33 @@ } define i32 @in_constant_42_vary(i32 %x, i32 %y, i32 %mask) { -; CHECK-LABEL: in_constant_42_vary: -; CHECK: # %bb.0: -; CHECK-NEXT: xori a0, a1, 42 -; CHECK-NEXT: and a0, a0, a2 -; CHECK-NEXT: xor a0, a0, a1 -; CHECK-NEXT: ret +; RV32I-LABEL: in_constant_42_vary: +; RV32I: # %bb.0: +; RV32I-NEXT: xori a0, a1, 42 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: xor a0, a0, a1 +; RV32I-NEXT: ret +; +; RV64I-LABEL: in_constant_42_vary: +; RV64I: # %bb.0: +; RV64I-NEXT: xori a0, a1, 42 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: xor a0, a0, a1 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: in_constant_42_vary: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: andn a0, a1, a2 +; RV32ZBB-NEXT: andi a1, a2, 42 +; RV32ZBB-NEXT: or a0, a1, a0 +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: in_constant_42_vary: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: andn a0, a1, a2 +; RV64ZBB-NEXT: andi a1, a2, 42 +; RV64ZBB-NEXT: or a0, a1, a0 +; RV64ZBB-NEXT: ret %n0 = xor i32 42, %y ; %x %n1 = and i32 %n0, %mask %r = xor i32 %n1, %y @@ -932,16 +1405,18 @@ ; ; RV32ZBB-LABEL: in_constant_42_vary_invmask: ; RV32ZBB: # %bb.0: -; RV32ZBB-NEXT: xori a0, a1, 42 -; RV32ZBB-NEXT: andn a0, a0, a2 -; RV32ZBB-NEXT: xor a0, a0, a1 +; RV32ZBB-NEXT: and a0, a1, a2 +; RV32ZBB-NEXT: addi a1, zero, 42 +; RV32ZBB-NEXT: andn a1, a1, a2 +; RV32ZBB-NEXT: or a0, a1, a0 ; RV32ZBB-NEXT: ret ; ; RV64ZBB-LABEL: in_constant_42_vary_invmask: ; RV64ZBB: # %bb.0: -; RV64ZBB-NEXT: xori a0, a1, 42 -; RV64ZBB-NEXT: andn a0, a0, a2 -; RV64ZBB-NEXT: xor a0, a0, a1 +; RV64ZBB-NEXT: and a0, a1, a2 +; RV64ZBB-NEXT: addi a1, zero, 42 +; RV64ZBB-NEXT: andn a1, a1, a2 +; RV64ZBB-NEXT: or a0, a1, a0 ; RV64ZBB-NEXT: ret %notmask = xor i32 %mask, -1 %n0 = xor i32 42, %y ; %x