llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-webassembly

Author: Julius Alexandre (wizardengineer)

<details>
<summary>Changes</summary>



---

Patch is 79.36 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/166709.diff


5 Files Affected:

- (added) llvm/test/CodeGen/WebAssembly/ctselect-fallback-edge-cases.ll (+376) 
- (added) llvm/test/CodeGen/WebAssembly/ctselect-fallback-patterns.ll (+641) 
- (added) llvm/test/CodeGen/WebAssembly/ctselect-fallback-vector.ll (+714) 
- (added) llvm/test/CodeGen/WebAssembly/ctselect-fallback.ll (+552) 
- (added) llvm/test/CodeGen/WebAssembly/ctselect-side-effects.ll (+226) 


``````````diff
diff --git a/llvm/test/CodeGen/WebAssembly/ctselect-fallback-edge-cases.ll 
b/llvm/test/CodeGen/WebAssembly/ctselect-fallback-edge-cases.ll
new file mode 100644
index 0000000000000..b0f7f2807debd
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/ctselect-fallback-edge-cases.ll
@@ -0,0 +1,376 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown -O3 -filetype=asm | FileCheck 
%s --check-prefix=W32
+; RUN: llc < %s -mtriple=wasm64-unknown-unknown -O3 -filetype=asm | FileCheck 
%s --check-prefix=W64
+
+; Test with small integer types
+define i1 @test_ctselect_i1(i1 %cond, i1 %a, i1 %b) {
+; W32-LABEL: test_ctselect_i1:
+; W32:         .functype test_ctselect_i1 (i32, i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_i1:
+; W64:         .functype test_ctselect_i1 (i32, i32, i32) -> (i32)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.xor
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_extremal_values:
+; W32:         .functype test_ctselect_extremal_values (i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 0
+; W32-NEXT:    i32.sub
+; W32-NEXT:    i32.const 2147483647
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    i32.const -2147483648
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_extremal_values:
+; W64:         .functype test_ctselect_extremal_values (i32) -> (i32)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.tee 0
+; W64-NEXT:    i32.sub
+; W64-NEXT:    i32.const 2147483647
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.add
+; W64-NEXT:    i32.const -2147483648
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_null_ptr:
+; W32:         .functype test_ctselect_null_ptr (i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.sub
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_null_ptr:
+; W64:         .functype test_ctselect_null_ptr (i32, i64) -> (i64)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i64.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i64.extend_i32_u
+; W64-NEXT:    i64.const 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    i64.sub
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_function_ptr:
+; W32:         .functype test_ctselect_function_ptr (i32, i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 0
+; W32-NEXT:    i32.sub
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_function_ptr:
+; W64:         .functype test_ctselect_function_ptr (i32, i64, i64) -> (i64)
+; W64-NEXT:    .local i64
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i64.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i64.extend_i32_u
+; W64-NEXT:    i64.const 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    local.tee 3
+; W64-NEXT:    i64.sub
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    local.get 3
+; W64-NEXT:    i64.const -1
+; W64-NEXT:    i64.add
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i64.and
+; W64-NEXT:    i64.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_ptr_cmp:
+; W32:         .functype test_ctselect_ptr_cmp (i32, i32, i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.eq
+; W32-NEXT:    i32.select
+; W32-NEXT:    local.tee 1
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 3
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_ptr_cmp:
+; W64:         .functype test_ctselect_ptr_cmp (i64, i64, i64, i64) -> (i64)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i64.const -1
+; W64-NEXT:    i64.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i64.eq
+; W64-NEXT:    i64.select
+; W64-NEXT:    local.tee 1
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i64.and
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i64.const -1
+; W64-NEXT:    i64.xor
+; W64-NEXT:    local.get 3
+; W64-NEXT:    i64.and
+; W64-NEXT:    i64.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_struct_ptr:
+; W32:         .functype test_ctselect_struct_ptr (i32, i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 0
+; W32-NEXT:    i32.sub
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_struct_ptr:
+; W64:         .functype test_ctselect_struct_ptr (i32, i64, i64) -> (i64)
+; W64-NEXT:    .local i64
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i64.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i64.extend_i32_u
+; W64-NEXT:    i64.const 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    local.tee 3
+; W64-NEXT:    i64.sub
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i64.and
+; W64-NEXT:    local.get 3
+; W64-NEXT:    i64.const -1
+; W64-NEXT:    i64.add
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i64.and
+; W64-NEXT:    i64.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_deeply_nested:
+; W32:         .functype test_ctselect_deeply_nested (i32, i32, i32, i32, i32, 
i32, i32, i32, i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 3
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 3
+; W32-NEXT:    i32.sub
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 2
+; W32-NEXT:    i32.sub
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 1
+; W32-NEXT:    i32.sub
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.tee 0
+; W32-NEXT:    i32.sub
+; W32-NEXT:    local.get 4
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 5
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 6
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 7
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 3
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.add
+; W32-NEXT:    local.get 8
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_deeply_nested:
+; W64:         .functype test_ctselect_deeply_nested (i32, i32, i32, i32, i32, 
i32, i32, i32, i32) -> (i32)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 3
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.tee 3
+; W64-NEXT:    i32.sub
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.tee 2
+; W64-NEXT:    i32.sub
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.tee 1
+; W64-NEXT:    i32.sub
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.tee 0
+; W64-NEXT:    i32.sub
+; W64-NEXT:    local.get 4
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.add
+; W64-NEXT:    local.get 5
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.add
+; W64-NEXT:    local.get 6
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.add
+; W64-NEXT:    local.get 7
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 3
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.add
+; W64-NEXT:    local.get 8
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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/WebAssembly/ctselect-fallback-patterns.ll 
b/llvm/test/CodeGen/WebAssembly/ctselect-fallback-patterns.ll
new file mode 100644
index 0000000000000..040ee44addb69
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/ctselect-fallback-patterns.ll
@@ -0,0 +1,641 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown -O3 -filetype=asm | FileCheck 
%s --check-prefix=W32
+; RUN: llc < %s -mtriple=wasm64-unknown-unknown -O3 -filetype=asm | FileCheck 
%s --check-prefix=W64
+
+; Test smin(x, 0) pattern
+define i32 @test_ctselect_smin_zero(i32 %x) {
+; W32-LABEL: test_ctselect_smin_zero:
+; W32:         .functype test_ctselect_smin_zero (i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 31
+; W32-NEXT:    i32.shr_s
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_smin_zero:
+; W64:         .functype test_ctselect_smin_zero (i32) -> (i32)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 31
+; W64-NEXT:    i32.shr_s
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.and
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_smax_zero:
+; W32:         .functype test_ctselect_smax_zero (i32) -> (i32)
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    i32.gt_s
+; W32-NEXT:    i32.select
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_smax_zero:
+; W64:         .functype test_ctselect_smax_zero (i32) -> (i32)
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    i32.gt_s
+; W64-NEXT:    i32.select
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_smin_generic:
+; W32:         .functype test_ctselect_smin_generic (i32, i32) -> (i32)
+; W32-NEXT:    .local i32
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.lt_s
+; W32-NEXT:    i32.select
+; W32-NEXT:    local.tee 2
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_smin_generic:
+; W64:         .functype test_ctselect_smin_generic (i32, i32) -> (i32)
+; W64-NEXT:    .local i32
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.lt_s
+; W64-NEXT:    i32.select
+; W64-NEXT:    local.tee 2
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.xor
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_smax_generic:
+; W32:         .functype test_ctselect_smax_generic (i32, i32) -> (i32)
+; W32-NEXT:    .local i32
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.gt_s
+; W32-NEXT:    i32.select
+; W32-NEXT:    local.tee 2
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_smax_generic:
+; W64:         .functype test_ctselect_smax_generic (i32, i32) -> (i32)
+; W64-NEXT:    .local i32
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.gt_s
+; W64-NEXT:    i32.select
+; W64-NEXT:    local.tee 2
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.xor
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_umin_generic:
+; W32:         .functype test_ctselect_umin_generic (i32, i32) -> (i32)
+; W32-NEXT:    .local i32
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.lt_u
+; W32-NEXT:    i32.select
+; W32-NEXT:    local.tee 2
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_umin_generic:
+; W64:         .functype test_ctselect_umin_generic (i32, i32) -> (i32)
+; W64-NEXT:    .local i32
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.lt_u
+; W64-NEXT:    i32.select
+; W64-NEXT:    local.tee 2
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.xor
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_umax_generic:
+; W32:         .functype test_ctselect_umax_generic (i32, i32) -> (i32)
+; W32-NEXT:    .local i32
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.gt_u
+; W32-NEXT:    i32.select
+; W32-NEXT:    local.tee 2
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 2
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_umax_generic:
+; W64:         .functype test_ctselect_umax_generic (i32, i32) -> (i32)
+; W64-NEXT:    .local i32
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.const 0
+; W64-NEXT:    local.get 0
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.gt_u
+; W64-NEXT:    i32.select
+; W64-NEXT:    local.tee 2
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.and
+; W64-NEXT:    local.get 2
+; W64-NEXT:    i32.const -1
+; W64-NEXT:    i32.xor
+; W64-NEXT:    local.get 1
+; W64-NEXT:    i32.and
+; W64-NEXT:    i32.or
+; W64-NEXT:    # fallthrough-return
+  %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) {
+; W32-LABEL: test_ctselect_abs:
+; W32:         .functype test_ctselect_abs (i32) -> (i32)
+; W32-NEXT:    .local i32
+; W32-NEXT:  # %bb.0:
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.const 31
+; W32-NEXT:    i32.shr_s
+; W32-NEXT:    local.tee 1
+; W32-NEXT:    i32.const 0
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.sub
+; W32-NEXT:    i32.and
+; W32-NEXT:    local.get 1
+; W32-NEXT:    i32.const -1
+; W32-NEXT:    i32.xor
+; W32-NEXT:    local.get 0
+; W32-NEXT:    i32.and
+; W32-NEXT:    i32.or
+; W32-NEXT:    # fallthrough-return
+;
+; W64-LABEL: test_ctselect_abs:
+; W64:         .functype test_ctselect_abs (i32) -> (i32)
+; W64-NEXT:    .local i32
+; W64-NEXT:  # %bb.0:
+; W64-NEXT:    local.get 0
+; W64-NEXT:    i32.const 31
+; W64-NEXT:    i32.shr_s
+; W6...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/166709
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to