Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 244 additions & 0 deletions llvm/test/CodeGen/Mips/ctselect-fallback-edge-cases.ll
Original file line number Diff line number Diff line change
@@ -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)
Loading
Loading