blob: 6a61412367f76fbdecab999d623e5f9d333deac5 [file] [log] [blame] [edit]
; 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 basic ct.select functionality for scalar types
define i8 @test_ctselect_i8(i1 %cond, i8 %a, i8 %b) {
; M32-LABEL: test_ctselect_i8:
; M32: # %bb.0:
; M32-NEXT: andi $2, $4, 1
; M32-NEXT: xor $1, $5, $6
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $6, $1
;
; M64-LABEL: test_ctselect_i8:
; M64: # %bb.0:
; M64-NEXT: sll $1, $4, 0
; M64-NEXT: xor $2, $5, $6
; M64-NEXT: andi $1, $1, 1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: negu $1, $1
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $6, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%result = call i8 @llvm.ct.select.i8(i1 %cond, i8 %a, i8 %b)
ret i8 %result
}
define i16 @test_ctselect_i16(i1 %cond, i16 %a, i16 %b) {
; M32-LABEL: test_ctselect_i16:
; M32: # %bb.0:
; M32-NEXT: andi $2, $4, 1
; M32-NEXT: xor $1, $5, $6
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $6, $1
;
; M64-LABEL: test_ctselect_i16:
; M64: # %bb.0:
; M64-NEXT: sll $1, $4, 0
; M64-NEXT: xor $2, $5, $6
; M64-NEXT: andi $1, $1, 1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: negu $1, $1
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $6, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%result = call i16 @llvm.ct.select.i16(i1 %cond, i16 %a, i16 %b)
ret i16 %result
}
define i32 @test_ctselect_i32(i1 %cond, i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_i32:
; M32: # %bb.0:
; M32-NEXT: andi $2, $4, 1
; M32-NEXT: xor $1, $5, $6
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $6, $1
;
; M64-LABEL: test_ctselect_i32:
; M64: # %bb.0:
; M64-NEXT: sll $1, $4, 0
; M64-NEXT: xor $2, $5, $6
; M64-NEXT: andi $1, $1, 1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: negu $1, $1
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $6, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
define i64 @test_ctselect_i64(i1 %cond, i64 %a, i64 %b) {
; M32-LABEL: test_ctselect_i64:
; M32: # %bb.0:
; M32-NEXT: lw $1, 16($sp)
; M32-NEXT: andi $3, $4, 1
; M32-NEXT: negu $3, $3
; M32-NEXT: xor $2, $6, $1
; M32-NEXT: and $2, $2, $3
; M32-NEXT: xor $2, $1, $2
; M32-NEXT: lw $1, 20($sp)
; M32-NEXT: xor $4, $7, $1
; M32-NEXT: and $3, $4, $3
; M32-NEXT: jr $ra
; M32-NEXT: xor $3, $1, $3
;
; M64-LABEL: test_ctselect_i64:
; M64: # %bb.0:
; M64-NEXT: andi $2, $4, 1
; M64-NEXT: xor $1, $5, $6
; M64-NEXT: dnegu $2, $2
; M64-NEXT: and $1, $1, $2
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $6, $1
%result = call i64 @llvm.ct.select.i64(i1 %cond, i64 %a, i64 %b)
ret i64 %result
}
define ptr @test_ctselect_ptr(i1 %cond, ptr %a, ptr %b) {
; M32-LABEL: test_ctselect_ptr:
; M32: # %bb.0:
; M32-NEXT: andi $2, $4, 1
; M32-NEXT: xor $1, $5, $6
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $6, $1
;
; M64-LABEL: test_ctselect_ptr:
; M64: # %bb.0:
; M64-NEXT: andi $2, $4, 1
; M64-NEXT: xor $1, $5, $6
; M64-NEXT: dnegu $2, $2
; M64-NEXT: and $1, $1, $2
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $6, $1
%result = call ptr @llvm.ct.select.p0(i1 %cond, ptr %a, ptr %b)
ret ptr %result
}
; Test with constant conditions
define i32 @test_ctselect_const_true(i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_const_true:
; M32: # %bb.0:
; M32-NEXT: jr $ra
; M32-NEXT: move $2, $4
;
; M64-LABEL: test_ctselect_const_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_const_false(i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_const_false:
; M32: # %bb.0:
; M32-NEXT: jr $ra
; M32-NEXT: move $2, $5
;
; M64-LABEL: test_ctselect_const_false:
; M64: # %bb.0:
; M64-NEXT: jr $ra
; M64-NEXT: sll $2, $5, 0
%result = call i32 @llvm.ct.select.i32(i1 false, i32 %a, i32 %b)
ret i32 %result
}
; Test with comparison conditions
define i32 @test_ctselect_icmp_eq(i32 %x, i32 %y, i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_icmp_eq:
; M32: # %bb.0:
; M32-NEXT: xor $2, $4, $5
; M32-NEXT: xor $1, $6, $7
; M32-NEXT: sltiu $2, $2, 1
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $7, $1
;
; M64-LABEL: test_ctselect_icmp_eq:
; M64: # %bb.0:
; M64-NEXT: sll $1, $5, 0
; M64-NEXT: sll $2, $4, 0
; M64-NEXT: xor $1, $2, $1
; M64-NEXT: xor $2, $6, $7
; M64-NEXT: sltiu $1, $1, 1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: negu $1, $1
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $7, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%cond = icmp eq i32 %x, %y
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
define i32 @test_ctselect_icmp_ne(i32 %x, i32 %y, i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_icmp_ne:
; M32: # %bb.0:
; M32-NEXT: xor $2, $4, $5
; M32-NEXT: xor $1, $6, $7
; M32-NEXT: sltu $2, $zero, $2
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $7, $1
;
; M64-LABEL: test_ctselect_icmp_ne:
; M64: # %bb.0:
; M64-NEXT: sll $1, $5, 0
; M64-NEXT: sll $2, $4, 0
; M64-NEXT: xor $1, $2, $1
; M64-NEXT: xor $2, $6, $7
; M64-NEXT: sltu $1, $zero, $1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: negu $1, $1
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $7, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%cond = icmp ne i32 %x, %y
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
define i32 @test_ctselect_icmp_slt(i32 %x, i32 %y, i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_icmp_slt:
; M32: # %bb.0:
; M32-NEXT: slt $2, $4, $5
; M32-NEXT: xor $1, $6, $7
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $7, $1
;
; M64-LABEL: test_ctselect_icmp_slt:
; M64: # %bb.0:
; M64-NEXT: sll $1, $5, 0
; M64-NEXT: sll $2, $4, 0
; M64-NEXT: slt $1, $2, $1
; M64-NEXT: xor $2, $6, $7
; M64-NEXT: negu $1, $1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $7, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%cond = icmp slt i32 %x, %y
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
define i32 @test_ctselect_icmp_ult(i32 %x, i32 %y, i32 %a, i32 %b) {
; M32-LABEL: test_ctselect_icmp_ult:
; M32: # %bb.0:
; M32-NEXT: sltu $2, $4, $5
; M32-NEXT: xor $1, $6, $7
; M32-NEXT: negu $2, $2
; M32-NEXT: and $1, $1, $2
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $7, $1
;
; M64-LABEL: test_ctselect_icmp_ult:
; M64: # %bb.0:
; M64-NEXT: sll $1, $5, 0
; M64-NEXT: sll $2, $4, 0
; M64-NEXT: sltu $1, $2, $1
; M64-NEXT: xor $2, $6, $7
; M64-NEXT: negu $1, $1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $7, 0
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%cond = icmp ult i32 %x, %y
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
; Test with memory operands
define i32 @test_ctselect_load(i1 %cond, ptr %p1, ptr %p2) {
; M32-LABEL: test_ctselect_load:
; M32: # %bb.0:
; M32-NEXT: lw $2, 0($6)
; M32-NEXT: lw $3, 0($5)
; M32-NEXT: andi $1, $4, 1
; M32-NEXT: negu $1, $1
; M32-NEXT: xor $3, $3, $2
; M32-NEXT: and $1, $3, $1
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $2, $1
;
; M64-LABEL: test_ctselect_load:
; M64: # %bb.0:
; M64-NEXT: sll $3, $4, 0
; M64-NEXT: lw $1, 0($6)
; M64-NEXT: lw $2, 0($5)
; M64-NEXT: andi $3, $3, 1
; M64-NEXT: xor $2, $2, $1
; M64-NEXT: negu $3, $3
; M64-NEXT: and $2, $2, $3
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $1, $2
%a = load i32, ptr %p1
%b = load i32, ptr %p2
%result = call i32 @llvm.ct.select.i32(i1 %cond, i32 %a, i32 %b)
ret i32 %result
}
; Test nested ctselect calls
define i32 @test_ctselect_nested(i1 %cond1, i1 %cond2, i32 %a, i32 %b, i32 %c) {
; M32-LABEL: test_ctselect_nested:
; M32: # %bb.0:
; M32-NEXT: andi $2, $5, 1
; M32-NEXT: xor $1, $6, $7
; M32-NEXT: andi $3, $4, 1
; M32-NEXT: negu $2, $2
; M32-NEXT: negu $3, $3
; M32-NEXT: and $1, $1, $2
; M32-NEXT: lw $2, 16($sp)
; M32-NEXT: xor $1, $7, $1
; M32-NEXT: xor $1, $1, $2
; M32-NEXT: and $1, $1, $3
; M32-NEXT: jr $ra
; M32-NEXT: xor $2, $2, $1
;
; M64-LABEL: test_ctselect_nested:
; M64: # %bb.0:
; M64-NEXT: sll $1, $5, 0
; M64-NEXT: xor $2, $6, $7
; M64-NEXT: sll $3, $4, 0
; M64-NEXT: andi $1, $1, 1
; M64-NEXT: sll $2, $2, 0
; M64-NEXT: andi $3, $3, 1
; M64-NEXT: negu $1, $1
; M64-NEXT: negu $3, $3
; M64-NEXT: and $1, $2, $1
; M64-NEXT: sll $2, $7, 0
; M64-NEXT: xor $1, $2, $1
; M64-NEXT: sll $2, $8, 0
; M64-NEXT: xor $1, $1, $2
; M64-NEXT: and $1, $1, $3
; M64-NEXT: jr $ra
; M64-NEXT: xor $2, $2, $1
%inner = call i32 @llvm.ct.select.i32(i1 %cond2, i32 %a, i32 %b)
%result = call i32 @llvm.ct.select.i32(i1 %cond1, i32 %inner, i32 %c)
ret i32 %result
}
; Declare the intrinsics
declare i8 @llvm.ct.select.i8(i1, i8, i8)
declare i16 @llvm.ct.select.i16(i1, i16, i16)
declare i32 @llvm.ct.select.i32(i1, i32, i32)
declare i64 @llvm.ct.select.i64(i1, i64, i64)
declare ptr @llvm.ct.select.p0(i1, ptr, ptr)