llvm/llvm/test/CodeGen/AArch64/min-max-combine.ll

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK-ISEL
; RUN: llc -mtriple=aarch64 %s -o - -mattr=cssc | FileCheck %s --check-prefixes=CHECK-CSSC
; RUN: llc -mtriple=aarch64 -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK-GLOBAL
; RUN: llc -mtriple=aarch64 -global-isel %s -o - -mattr=cssc | FileCheck %s --check-prefixes=CHECK-CSSC

; These tests check for @llvm.smax, @llvm.smin combines.

; SMAX

declare i8 @llvm.smax.i8(i8 %a, i8 %b) readnone

define i8 @smaxi8_zero(i8 %a) {
; CHECK-ISEL-LABEL: smaxi8_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    sxtb w8, w0
; CHECK-ISEL-NEXT:    bic w0, w8, w8, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smaxi8_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    sxtb w8, w0
; CHECK-CSSC-NEXT:    smax w0, w8, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smaxi8_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    sxtb w8, w0
; CHECK-GLOBAL-NEXT:    cmp w8, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, gt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i8 @llvm.smax.i8(i8 %a, i8 0)
  ret i8 %c
}

declare i16 @llvm.smax.i16(i16 %a, i16 %b) readnone

define i16 @smaxi16_zero(i16 %a) {
; CHECK-ISEL-LABEL: smaxi16_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    sxth w8, w0
; CHECK-ISEL-NEXT:    bic w0, w8, w8, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smaxi16_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    sxth w8, w0
; CHECK-CSSC-NEXT:    smax w0, w8, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smaxi16_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    sxth w8, w0
; CHECK-GLOBAL-NEXT:    cmp w8, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, gt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i16 @llvm.smax.i16(i16 %a, i16 0)
  ret i16 %c
}

declare i32 @llvm.smax.i32(i32 %a, i32 %b) readnone

define i32 @smaxi32_zero(i32 %a) {
; CHECK-ISEL-LABEL: smaxi32_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    bic w0, w0, w0, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smaxi32_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    smax w0, w0, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smaxi32_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    cmp w0, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, gt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i32 @llvm.smax.i32(i32 %a, i32 0)
  ret i32 %c
}

declare i64 @llvm.smax.i64(i64 %a, i64 %b) readnone

define i64 @smaxi64_zero(i64 %a) {
; CHECK-ISEL-LABEL: smaxi64_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    bic x0, x0, x0, asr #63
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smaxi64_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    smax x0, x0, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smaxi64_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    cmp x0, #0
; CHECK-GLOBAL-NEXT:    csel x0, x0, xzr, gt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i64 @llvm.smax.i64(i64 %a, i64 0)
  ret i64 %c
}

; SMIN

declare i8 @llvm.smin.i8(i8 %a, i8 %b) readnone

define i8 @smini8_zero(i8 %a) {
; CHECK-ISEL-LABEL: smini8_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    sxtb w8, w0
; CHECK-ISEL-NEXT:    and w0, w8, w8, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smini8_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    sxtb w8, w0
; CHECK-CSSC-NEXT:    smin w0, w8, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smini8_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    sxtb w8, w0
; CHECK-GLOBAL-NEXT:    cmp w8, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, lt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i8 @llvm.smin.i8(i8 %a, i8 0)
  ret i8 %c
}

declare i16 @llvm.smin.i16(i16 %a, i16 %b) readnone

define i16 @smini16_zero(i16 %a) {
; CHECK-ISEL-LABEL: smini16_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    sxth w8, w0
; CHECK-ISEL-NEXT:    and w0, w8, w8, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smini16_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    sxth w8, w0
; CHECK-CSSC-NEXT:    smin w0, w8, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smini16_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    sxth w8, w0
; CHECK-GLOBAL-NEXT:    cmp w8, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, lt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i16 @llvm.smin.i16(i16 %a, i16 0)
  ret i16 %c
}

declare i32 @llvm.smin.i32(i32 %a, i32 %b) readnone

define i32 @smini32_zero(i32 %a) {
; CHECK-ISEL-LABEL: smini32_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    and w0, w0, w0, asr #31
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smini32_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    smin w0, w0, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smini32_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    cmp w0, #0
; CHECK-GLOBAL-NEXT:    csel w0, w0, wzr, lt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i32 @llvm.smin.i32(i32 %a, i32 0)
  ret i32 %c
}

declare i64 @llvm.smin.i64(i64 %a, i64 %b) readnone

define i64 @smini64_zero(i64 %a) {
; CHECK-ISEL-LABEL: smini64_zero:
; CHECK-ISEL:       // %bb.0:
; CHECK-ISEL-NEXT:    and x0, x0, x0, asr #63
; CHECK-ISEL-NEXT:    ret
;
; CHECK-CSSC-LABEL: smini64_zero:
; CHECK-CSSC:       // %bb.0:
; CHECK-CSSC-NEXT:    smin x0, x0, #0
; CHECK-CSSC-NEXT:    ret
;
; CHECK-GLOBAL-LABEL: smini64_zero:
; CHECK-GLOBAL:       // %bb.0:
; CHECK-GLOBAL-NEXT:    cmp x0, #0
; CHECK-GLOBAL-NEXT:    csel x0, x0, xzr, lt
; CHECK-GLOBAL-NEXT:    ret
  %c = call i64 @llvm.smin.i64(i64 %a, i64 0)
  ret i64 %c
}