llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-mips Author: Julius Alexandre (wizardengineer) <details> <summary>Changes</summary> --- Patch is 70.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/166705.diff 5 Files Affected: - (added) llvm/test/CodeGen/Mips/ctselect-fallback-edge-cases.ll (+244) - (added) llvm/test/CodeGen/Mips/ctselect-fallback-patterns.ll (+426) - (added) llvm/test/CodeGen/Mips/ctselect-fallback-vector.ll (+830) - (added) llvm/test/CodeGen/Mips/ctselect-fallback.ll (+371) - (added) llvm/test/CodeGen/Mips/ctselect-side-effects.ll (+183) ``````````diff diff --git a/llvm/test/CodeGen/Mips/ctselect-fallback-edge-cases.ll b/llvm/test/CodeGen/Mips/ctselect-fallback-edge-cases.ll new file mode 100644 index 0000000000000..f1831a625d4a4 --- /dev/null +++ b/llvm/test/CodeGen/Mips/ctselect-fallback-edge-cases.ll @@ -0,0 +1,244 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -O3 | FileCheck %s --check-prefix=M32 +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -O3 | FileCheck %s --check-prefix=M64 + +; Portable edge case tests + +; Test with small integer types +define i1 @test_ctselect_i1(i1 %cond, i1 %a, i1 %b) { +; M32-LABEL: test_ctselect_i1: +; M32: # %bb.0: +; M32-NEXT: xori $2, $4, 1 +; M32-NEXT: and $1, $4, $5 +; M32-NEXT: and $2, $2, $6 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $1, $2 +; +; M64-LABEL: test_ctselect_i1: +; M64: # %bb.0: +; M64-NEXT: sll $2, $4, 0 +; M64-NEXT: sll $1, $6, 0 +; M64-NEXT: xori $2, $2, 1 +; M64-NEXT: and $1, $2, $1 +; M64-NEXT: and $2, $4, $5 +; M64-NEXT: sll $2, $2, 0 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %result = call i1 @llvm.ct.select.i1(i1 %cond, i1 %a, i1 %b) + ret i1 %result +} + +; Test with extremal values +define i32 @test_ctselect_extremal_values(i1 %cond) { +; M32-LABEL: test_ctselect_extremal_values: +; M32: # %bb.0: +; M32-NEXT: lui $3, 32767 +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: negu $2, $1 +; M32-NEXT: ori $3, $3, 65535 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $2, $3 +; M32-NEXT: lui $3, 32768 +; M32-NEXT: and $1, $1, $3 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_extremal_values: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: lui $3, 32767 +; M64-NEXT: andi $1, $1, 1 +; M64-NEXT: ori $3, $3, 65535 +; M64-NEXT: negu $2, $1 +; M64-NEXT: addiu $1, $1, -1 +; M64-NEXT: and $2, $2, $3 +; M64-NEXT: lui $3, 32768 +; M64-NEXT: and $1, $1, $3 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %result = call i32 @llvm.ct.select.i32(i1 %cond, i32 2147483647, i32 -2147483648) + ret i32 %result +} + +; Test with null pointers +define ptr @test_ctselect_null_ptr(i1 %cond, ptr %ptr) { +; M32-LABEL: test_ctselect_null_ptr: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: negu $1, $1 +; M32-NEXT: jr $ra +; M32-NEXT: and $2, $1, $5 +; +; M64-LABEL: test_ctselect_null_ptr: +; M64: # %bb.0: +; M64-NEXT: andi $1, $4, 1 +; M64-NEXT: dnegu $1, $1 +; M64-NEXT: jr $ra +; M64-NEXT: and $2, $1, $5 + %result = call ptr @llvm.ct.select.p0(i1 %cond, ptr %ptr, ptr null) + ret ptr %result +} + +; Test with function pointers +define ptr @test_ctselect_function_ptr(i1 %cond, ptr %func1, ptr %func2) { +; M32-LABEL: test_ctselect_function_ptr: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: negu $2, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $2, $5 +; M32-NEXT: and $1, $1, $6 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_function_ptr: +; M64: # %bb.0: +; M64-NEXT: andi $1, $4, 1 +; M64-NEXT: dnegu $2, $1 +; M64-NEXT: daddiu $1, $1, -1 +; M64-NEXT: and $2, $2, $5 +; M64-NEXT: and $1, $1, $6 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %result = call ptr @llvm.ct.select.p0(i1 %cond, ptr %func1, ptr %func2) + ret ptr %result +} + +; Test with condition from icmp on pointers +define ptr @test_ctselect_ptr_cmp(ptr %p1, ptr %p2, ptr %a, ptr %b) { +; M32-LABEL: test_ctselect_ptr_cmp: +; M32: # %bb.0: +; M32-NEXT: xor $1, $4, $5 +; M32-NEXT: sltu $1, $zero, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $6 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $7 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_ptr_cmp: +; M64: # %bb.0: +; M64-NEXT: xor $1, $4, $5 +; M64-NEXT: daddiu $3, $zero, -1 +; M64-NEXT: daddiu $2, $zero, -1 +; M64-NEXT: movn $3, $zero, $1 +; M64-NEXT: xor $2, $3, $2 +; M64-NEXT: and $1, $3, $6 +; M64-NEXT: and $2, $2, $7 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $1, $2 + %cmp = icmp eq ptr %p1, %p2 + %result = call ptr @llvm.ct.select.p0(i1 %cmp, ptr %a, ptr %b) + ret ptr %result +} + +; Test with struct pointer types +%struct.pair = type { i32, i32 } + +define ptr @test_ctselect_struct_ptr(i1 %cond, ptr %a, ptr %b) { +; M32-LABEL: test_ctselect_struct_ptr: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: negu $2, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $2, $5 +; M32-NEXT: and $1, $1, $6 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_struct_ptr: +; M64: # %bb.0: +; M64-NEXT: andi $1, $4, 1 +; M64-NEXT: dnegu $2, $1 +; M64-NEXT: daddiu $1, $1, -1 +; M64-NEXT: and $2, $2, $5 +; M64-NEXT: and $1, $1, $6 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %result = call ptr @llvm.ct.select.p0(i1 %cond, ptr %a, ptr %b) + ret ptr %result +} + +; Test with deeply nested conditions +define i32 @test_ctselect_deeply_nested(i1 %c1, i1 %c2, i1 %c3, i1 %c4, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) { +; M32-LABEL: test_ctselect_deeply_nested: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: lw $3, 16($sp) +; M32-NEXT: lw $9, 32($sp) +; M32-NEXT: lw $8, 28($sp) +; M32-NEXT: negu $2, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $2, $3 +; M32-NEXT: lw $3, 20($sp) +; M32-NEXT: and $1, $1, $3 +; M32-NEXT: andi $3, $5, 1 +; M32-NEXT: or $1, $2, $1 +; M32-NEXT: andi $2, $6, 1 +; M32-NEXT: andi $6, $7, 1 +; M32-NEXT: negu $4, $3 +; M32-NEXT: addiu $3, $3, -1 +; M32-NEXT: addiu $7, $6, -1 +; M32-NEXT: and $1, $4, $1 +; M32-NEXT: addiu $5, $2, -1 +; M32-NEXT: negu $2, $2 +; M32-NEXT: negu $6, $6 +; M32-NEXT: and $4, $7, $9 +; M32-NEXT: lw $7, 24($sp) +; M32-NEXT: and $5, $5, $8 +; M32-NEXT: and $3, $3, $7 +; M32-NEXT: or $1, $1, $3 +; M32-NEXT: and $1, $2, $1 +; M32-NEXT: or $1, $1, $5 +; M32-NEXT: and $1, $6, $1 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $1, $4 +; +; M64-LABEL: test_ctselect_deeply_nested: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sll $3, $8, 0 +; M64-NEXT: sll $4, $5, 0 +; M64-NEXT: lw $8, 0($sp) +; M64-NEXT: andi $1, $1, 1 +; M64-NEXT: andi $4, $4, 1 +; M64-NEXT: negu $2, $1 +; M64-NEXT: addiu $1, $1, -1 +; M64-NEXT: negu $5, $4 +; M64-NEXT: addiu $4, $4, -1 +; M64-NEXT: and $2, $2, $3 +; M64-NEXT: sll $3, $9, 0 +; M64-NEXT: and $1, $1, $3 +; M64-NEXT: sll $3, $11, 0 +; M64-NEXT: or $1, $2, $1 +; M64-NEXT: sll $2, $6, 0 +; M64-NEXT: sll $6, $7, 0 +; M64-NEXT: andi $2, $2, 1 +; M64-NEXT: and $1, $5, $1 +; M64-NEXT: andi $6, $6, 1 +; M64-NEXT: addiu $5, $2, -1 +; M64-NEXT: negu $2, $2 +; M64-NEXT: addiu $7, $6, -1 +; M64-NEXT: negu $6, $6 +; M64-NEXT: and $3, $5, $3 +; M64-NEXT: sll $5, $10, 0 +; M64-NEXT: and $7, $7, $8 +; M64-NEXT: and $4, $4, $5 +; M64-NEXT: or $1, $1, $4 +; M64-NEXT: and $1, $2, $1 +; M64-NEXT: or $1, $1, $3 +; M64-NEXT: and $1, $6, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $1, $7 + %sel1 = call i32 @llvm.ct.select.i32(i1 %c1, i32 %a, i32 %b) + %sel2 = call i32 @llvm.ct.select.i32(i1 %c2, i32 %sel1, i32 %c) + %sel3 = call i32 @llvm.ct.select.i32(i1 %c3, i32 %sel2, i32 %d) + %sel4 = call i32 @llvm.ct.select.i32(i1 %c4, i32 %sel3, i32 %e) + ret i32 %sel4 +} + +; Declare the intrinsics +declare i1 @llvm.ct.select.i1(i1, i1, i1) +declare i32 @llvm.ct.select.i32(i1, i32, i32) +declare ptr @llvm.ct.select.p0(i1, ptr, ptr) diff --git a/llvm/test/CodeGen/Mips/ctselect-fallback-patterns.ll b/llvm/test/CodeGen/Mips/ctselect-fallback-patterns.ll new file mode 100644 index 0000000000000..2e65e586ce5fa --- /dev/null +++ b/llvm/test/CodeGen/Mips/ctselect-fallback-patterns.ll @@ -0,0 +1,426 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=mipsel-unknown-linux-gnu -O3 | FileCheck %s --check-prefix=M32 +; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -O3 | FileCheck %s --check-prefix=M64 + +; Test smin(x, 0) pattern +define i32 @test_ctselect_smin_zero(i32 %x) { +; M32-LABEL: test_ctselect_smin_zero: +; M32: # %bb.0: +; M32-NEXT: sra $1, $4, 31 +; M32-NEXT: jr $ra +; M32-NEXT: and $2, $1, $4 +; +; M64-LABEL: test_ctselect_smin_zero: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sra $2, $1, 31 +; M64-NEXT: jr $ra +; M64-NEXT: and $2, $2, $1 + %cmp = icmp slt i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 0) + ret i32 %result +} + +; Test smax(x, 0) pattern +define i32 @test_ctselect_smax_zero(i32 %x) { +; M32-LABEL: test_ctselect_smax_zero: +; M32: # %bb.0: +; M32-NEXT: slti $1, $4, 1 +; M32-NEXT: movn $4, $zero, $1 +; M32-NEXT: jr $ra +; M32-NEXT: move $2, $4 +; +; M64-LABEL: test_ctselect_smax_zero: +; M64: # %bb.0: +; M64-NEXT: sll $2, $4, 0 +; M64-NEXT: slti $1, $2, 1 +; M64-NEXT: jr $ra +; M64-NEXT: movn $2, $zero, $1 + %cmp = icmp sgt i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 0) + ret i32 %result +} + +; Test generic smin pattern +define i32 @test_ctselect_smin_generic(i32 %x, i32 %y) { +; M32-LABEL: test_ctselect_smin_generic: +; M32: # %bb.0: +; M32-NEXT: slt $1, $4, $5 +; M32-NEXT: xori $1, $1, 1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_smin_generic: +; M64: # %bb.0: +; M64-NEXT: sll $1, $5, 0 +; M64-NEXT: sll $2, $4, 0 +; M64-NEXT: slt $3, $2, $1 +; M64-NEXT: xori $3, $3, 1 +; M64-NEXT: addiu $3, $3, -1 +; M64-NEXT: and $2, $3, $2 +; M64-NEXT: not $3, $3 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %cmp = icmp slt i32 %x, %y + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 %y) + ret i32 %result +} + +; Test generic smax pattern +define i32 @test_ctselect_smax_generic(i32 %x, i32 %y) { +; M32-LABEL: test_ctselect_smax_generic: +; M32: # %bb.0: +; M32-NEXT: slt $1, $5, $4 +; M32-NEXT: xori $1, $1, 1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_smax_generic: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sll $2, $5, 0 +; M64-NEXT: slt $3, $2, $1 +; M64-NEXT: xori $3, $3, 1 +; M64-NEXT: addiu $3, $3, -1 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: not $3, $3 +; M64-NEXT: and $2, $3, $2 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $1, $2 + %cmp = icmp sgt i32 %x, %y + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 %y) + ret i32 %result +} + +; Test umin pattern +define i32 @test_ctselect_umin_generic(i32 %x, i32 %y) { +; M32-LABEL: test_ctselect_umin_generic: +; M32: # %bb.0: +; M32-NEXT: sltu $1, $4, $5 +; M32-NEXT: xori $1, $1, 1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_umin_generic: +; M64: # %bb.0: +; M64-NEXT: sll $1, $5, 0 +; M64-NEXT: sll $2, $4, 0 +; M64-NEXT: sltu $3, $2, $1 +; M64-NEXT: xori $3, $3, 1 +; M64-NEXT: addiu $3, $3, -1 +; M64-NEXT: and $2, $3, $2 +; M64-NEXT: not $3, $3 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %cmp = icmp ult i32 %x, %y + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 %y) + ret i32 %result +} + +; Test umax pattern +define i32 @test_ctselect_umax_generic(i32 %x, i32 %y) { +; M32-LABEL: test_ctselect_umax_generic: +; M32: # %bb.0: +; M32-NEXT: sltu $1, $5, $4 +; M32-NEXT: xori $1, $1, 1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_umax_generic: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sll $2, $5, 0 +; M64-NEXT: sltu $3, $2, $1 +; M64-NEXT: xori $3, $3, 1 +; M64-NEXT: addiu $3, $3, -1 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: not $3, $3 +; M64-NEXT: and $2, $3, $2 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $1, $2 + %cmp = icmp ugt i32 %x, %y + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 %y) + ret i32 %result +} + +; Test abs pattern +define i32 @test_ctselect_abs(i32 %x) { +; M32-LABEL: test_ctselect_abs: +; M32: # %bb.0: +; M32-NEXT: negu $1, $4 +; M32-NEXT: sra $2, $4, 31 +; M32-NEXT: and $1, $2, $1 +; M32-NEXT: not $2, $2 +; M32-NEXT: and $2, $2, $4 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $1, $2 +; +; M64-LABEL: test_ctselect_abs: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: negu $2, $1 +; M64-NEXT: sra $3, $1, 31 +; M64-NEXT: and $2, $3, $2 +; M64-NEXT: not $3, $3 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %neg = sub i32 0, %x + %cmp = icmp slt i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %neg, i32 %x) + ret i32 %result +} + +; Test nabs pattern (negative abs) +define i32 @test_ctselect_nabs(i32 %x) { +; M32-LABEL: test_ctselect_nabs: +; M32: # %bb.0: +; M32-NEXT: sra $1, $4, 31 +; M32-NEXT: negu $3, $4 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $3 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_nabs: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sra $2, $1, 31 +; M64-NEXT: and $3, $2, $1 +; M64-NEXT: negu $1, $1 +; M64-NEXT: not $2, $2 +; M64-NEXT: and $1, $2, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $3, $1 + %neg = sub i32 0, %x + %cmp = icmp slt i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 %x, i32 %neg) + ret i32 %result +} + +; Test sign extension pattern +define i32 @test_ctselect_sign_extend(i32 %x) { +; M32-LABEL: test_ctselect_sign_extend: +; M32: # %bb.0: +; M32-NEXT: jr $ra +; M32-NEXT: sra $2, $4, 31 +; +; M64-LABEL: test_ctselect_sign_extend: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: jr $ra +; M64-NEXT: sra $2, $1, 31 + %cmp = icmp slt i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 -1, i32 0) + ret i32 %result +} + +; Test zero extension pattern +define i32 @test_ctselect_zero_extend(i32 %x) { +; M32-LABEL: test_ctselect_zero_extend: +; M32: # %bb.0: +; M32-NEXT: jr $ra +; M32-NEXT: sltu $2, $zero, $4 +; +; M64-LABEL: test_ctselect_zero_extend: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: jr $ra +; M64-NEXT: sltu $2, $zero, $1 + %cmp = icmp ne i32 %x, 0 + %result = call i32 @llvm.ct.select.i32(i1 %cmp, i32 1, i32 0) + ret i32 %result +} + +; Test constant folding with known condition +define i32 @test_ctselect_constant_folding_true(i32 %a, i32 %b) { +; M32-LABEL: test_ctselect_constant_folding_true: +; M32: # %bb.0: +; M32-NEXT: jr $ra +; M32-NEXT: move $2, $4 +; +; M64-LABEL: test_ctselect_constant_folding_true: +; M64: # %bb.0: +; M64-NEXT: jr $ra +; M64-NEXT: sll $2, $4, 0 + %result = call i32 @llvm.ct.select.i32(i1 true, i32 %a, i32 %b) + ret i32 %result +} + +define i32 @test_ctselect_constant_folding_false(i32 %a, i32 %b) { +; M32-LABEL: test_ctselect_constant_folding_false: +; M32: # %bb.0: +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $zero, $5 +; +; M64-LABEL: test_ctselect_constant_folding_false: +; M64: # %bb.0: +; M64-NEXT: sll $1, $5, 0 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $zero, $1 + %result = call i32 @llvm.ct.select.i32(i1 false, i32 %a, i32 %b) + ret i32 %result +} + +; Test with identical operands +define i32 @test_ctselect_identical_operands(i1 %cond, i32 %x) { +; M32-LABEL: test_ctselect_identical_operands: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: negu $2, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $2, $5 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_identical_operands: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sll $3, $5, 0 +; M64-NEXT: andi $1, $1, 1 +; M64-NEXT: negu $2, $1 +; M64-NEXT: addiu $1, $1, -1 +; M64-NEXT: and $2, $2, $3 +; M64-NEXT: and $1, $1, $3 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %x, i32 %x) + ret i32 %result +} + +; Test with inverted condition +define i32 @test_ctselect_inverted_condition(i32 %x, i32 %y, i32 %a, i32 %b) { +; M32-LABEL: test_ctselect_inverted_condition: +; M32: # %bb.0: +; M32-NEXT: xor $1, $4, $5 +; M32-NEXT: sltiu $1, $1, 1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: and $2, $1, $6 +; M32-NEXT: not $1, $1 +; M32-NEXT: and $1, $1, $7 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $2, $1 +; +; M64-LABEL: test_ctselect_inverted_condition: +; M64: # %bb.0: +; M64-NEXT: sll $1, $5, 0 +; M64-NEXT: sll $2, $4, 0 +; M64-NEXT: sll $3, $7, 0 +; M64-NEXT: xor $1, $2, $1 +; M64-NEXT: sll $2, $6, 0 +; M64-NEXT: sltiu $1, $1, 1 +; M64-NEXT: addiu $1, $1, -1 +; M64-NEXT: and $2, $1, $2 +; M64-NEXT: not $1, $1 +; M64-NEXT: and $1, $1, $3 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $2, $1 + %cmp = icmp eq i32 %x, %y + %not_cmp = xor i1 %cmp, true + %result = call i32 @llvm.ct.select.i32(i1 %not_cmp, i32 %a, i32 %b) + ret i32 %result +} + +; Test chain of ct.select operations +define i32 @test_ctselect_chain(i1 %c1, i1 %c2, i1 %c3, i32 %a, i32 %b, i32 %c, i32 %d) { +; M32-LABEL: test_ctselect_chain: +; M32: # %bb.0: +; M32-NEXT: andi $1, $4, 1 +; M32-NEXT: andi $3, $5, 1 +; M32-NEXT: lw $5, 16($sp) +; M32-NEXT: negu $2, $1 +; M32-NEXT: addiu $1, $1, -1 +; M32-NEXT: negu $4, $3 +; M32-NEXT: addiu $3, $3, -1 +; M32-NEXT: and $1, $1, $5 +; M32-NEXT: and $2, $2, $7 +; M32-NEXT: lw $5, 24($sp) +; M32-NEXT: or $1, $2, $1 +; M32-NEXT: andi $2, $6, 1 +; M32-NEXT: and $1, $4, $1 +; M32-NEXT: addiu $4, $2, -1 +; M32-NEXT: negu $2, $2 +; M32-NEXT: and $4, $4, $5 +; M32-NEXT: lw $5, 20($sp) +; M32-NEXT: and $3, $3, $5 +; M32-NEXT: or $1, $1, $3 +; M32-NEXT: and $1, $2, $1 +; M32-NEXT: jr $ra +; M32-NEXT: or $2, $1, $4 +; +; M64-LABEL: test_ctselect_chain: +; M64: # %bb.0: +; M64-NEXT: sll $1, $4, 0 +; M64-NEXT: sll $3, $7, 0 +; M64-NEXT: sll $4, $5, 0 +; M64-NEXT: andi $1, $1, 1 +; M64-NEXT: andi $4, $4, 1 +; M64-NEXT: negu $2, $1 +; M64-NEXT: addiu $1, $1, -1 +; M64-NEXT: negu $5, $4 +; M64-NEXT: addiu $4, $4, -1 +; M64-NEXT: and $2, $2, $3 +; M64-NEXT: sll $3, $8, 0 +; M64-NEXT: and $1, $1, $3 +; M64-NEXT: sll $3, $6, 0 +; M64-NEXT: sll $6, $10, 0 +; M64-NEXT: or $1, $2, $1 +; M64-NEXT: andi $3, $3, 1 +; M64-NEXT: and $1, $5, $1 +; M64-NEXT: sll $5, $9, 0 +; M64-NEXT: addiu $2, $3, -1 +; M64-NEXT: negu $3, $3 +; M64-NEXT: and $4, $4, $5 +; M64-NEXT: and $2, $2, $6 +; M64-NEXT: or $1, $1, $4 +; M64-NEXT: and $1, $3, $1 +; M64-NEXT: jr $ra +; M64-NEXT: or $2, $1, $2 + %sel1 = call i32 @llvm.ct.select.i32(i1 %c1, i32 %a, i32 %b) + %sel2 = call i32 @llvm.ct.select.i32(i1 %c2, i32 %sel1, i32 %c) + %sel3 = call i32 @llvm.ct.select.i32(i1 %c3, i32 %sel2, i32 %d) + ret i32 %sel3 +} + +; Test for 64-bit operations (supported on all 64-bit architectures) +define i64 @test_ctselect_i64_smin_zero(i64 %x) { +; M32-LABEL: test_ctselect_i64_smin_zero: +; M32: # %bb.0: +; M32-NEXT: sra $1, $5, 31 +; M32-NEXT: and $2, $1, $4 +; M32-NEXT: jr $ra +; M32-NEXT: and $3, $1, $5 +; +; M64-LABEL: test_ctselect_i64_smin_zero: +; M64: # %bb.0: +; M64-NEXT: dsra ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/166705 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
