diff --git a/llvm/test/CodeGen/RISCV/select-and.ll b/llvm/test/CodeGen/RISCV/select-and.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/select-and.ll @@ -0,0 +1,37 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32I %s +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64I %s + +;; There are a few different ways to lower (select (and A, B), X, Y). This test +;; ensures that we do so with as few branches as possible. + +define signext i32 @select_of_and(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) nounwind { +; RV32I-LABEL: select_of_and: +; RV32I: # %bb.0: +; RV32I-NEXT: xor a4, a0, a1 +; RV32I-NEXT: xor a2, a2, a3 +; RV32I-NEXT: or a2, a4, a2 +; RV32I-NEXT: beqz a2, .LBB0_2 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: .LBB0_2: +; RV32I-NEXT: ret +; +; RV64I-LABEL: select_of_and: +; RV64I: # %bb.0: +; RV64I-NEXT: xor a4, a0, a1 +; RV64I-NEXT: xor a2, a2, a3 +; RV64I-NEXT: or a2, a4, a2 +; RV64I-NEXT: beqz a2, .LBB0_2 +; RV64I-NEXT: # %bb.1: +; RV64I-NEXT: mv a0, a1 +; RV64I-NEXT: .LBB0_2: +; RV64I-NEXT: ret + %1 = icmp eq i32 %a, %b + %2 = icmp eq i32 %c, %d + %3 = and i1 %1, %2 + %4 = select i1 %3, i32 %a, i32 %b + ret i32 %4 +} diff --git a/llvm/test/CodeGen/RISCV/select-or.ll b/llvm/test/CodeGen/RISCV/select-or.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/select-or.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32I %s +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV64I %s + +;; There are a few different ways to lower (select (or A, B), X, Y). This test +;; ensures that we do so with as few branches as possible. + +define signext i32 @select_of_or(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d) nounwind { +; RV32I-LABEL: select_of_or: +; RV32I: # %bb.0: +; RV32I-NEXT: mv a4, a0 +; RV32I-NEXT: bne a2, a3, .LBB0_3 +; RV32I-NEXT: # %bb.1: +; RV32I-NEXT: bne a0, a1, .LBB0_4 +; RV32I-NEXT: .LBB0_2: +; RV32I-NEXT: ret +; RV32I-NEXT: .LBB0_3: +; RV32I-NEXT: mv a4, a1 +; RV32I-NEXT: beq a0, a1, .LBB0_2 +; RV32I-NEXT: .LBB0_4: +; RV32I-NEXT: mv a0, a4 +; RV32I-NEXT: ret +; +; RV64I-LABEL: select_of_or: +; RV64I: # %bb.0: +; RV64I-NEXT: mv a4, a0 +; RV64I-NEXT: bne a2, a3, .LBB0_3 +; RV64I-NEXT: # %bb.1: +; RV64I-NEXT: bne a0, a1, .LBB0_4 +; RV64I-NEXT: .LBB0_2: +; RV64I-NEXT: ret +; RV64I-NEXT: .LBB0_3: +; RV64I-NEXT: mv a4, a1 +; RV64I-NEXT: beq a0, a1, .LBB0_2 +; RV64I-NEXT: .LBB0_4: +; RV64I-NEXT: mv a0, a4 +; RV64I-NEXT: ret + %1 = icmp eq i32 %a, %b + %2 = icmp eq i32 %c, %d + %3 = or i1 %1, %2 + %4 = select i1 %3, i32 %a, i32 %b + ret i32 %4 +}