blob: 3d1d3af7221f05706dd97166be7fd2f7e192bf82 [file] [log] [blame]
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=aarch64 -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=LOWER
# RUN: llc -mtriple=aarch64 -global-isel -start-before=aarch64-postlegalizer-lowering -stop-after=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=SELECT
# Verify that we will adjust the constant + predicate of a compare when it will
# allow us to fold an immediate into a compare.
...
---
name: slt_to_sle_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x slt c => x sle c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: slt_to_sle_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: slt_to_sle_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 4097
%cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: slt_to_sle_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x slt c => x sle c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: slt_to_sle_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: slt_to_sle_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 4097
%cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sge_to_sgt_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x sge c => x sgt c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: sge_to_sgt_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sge_to_sgt_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 4097
%cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sge_to_sgt_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x sge c => x sgt c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: sge_to_sgt_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sge_to_sgt_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 4097
%cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: ult_to_ule_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x ult c => x ule c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: ult_to_ule_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: ult_to_ule_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 4097
%cmp:_(s32) = G_ICMP intpred(ult), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: ult_to_ule_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x ult c => x ule c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: ult_to_ule_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: ult_to_ule_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 4097
%cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: uge_to_ugt_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x uge c => x ugt c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: uge_to_ugt_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: uge_to_ugt_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 4097
%cmp:_(s32) = G_ICMP intpred(uge), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: uge_to_ugt_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x uge c => x ugt c - 1
;
; log_2(4096) == 12, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: uge_to_ugt_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096
; LOWER: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: uge_to_ugt_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 1, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 4097
%cmp:_(s32) = G_ICMP intpred(uge), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sle_to_slt_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x sle c => x slt c + 1
;
; log_2(8192) == 13, so we can represent this as a 12 bit value with a
; left shift.
;
; (We can't use 4095 here, because that's a legal arithmetic immediate.)
; LOWER-LABEL: name: sle_to_slt_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192
; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sle_to_slt_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 2, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 8191
%cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sle_to_slt_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x sle c => x slt c + 1
;
; log_2(8192) == 13, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: sle_to_slt_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192
; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sle_to_slt_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 2, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 8191
%cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sgt_to_sge_s32
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; x sgt c => s sge c + 1
;
; log_2(8192) == 13, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: sgt_to_sge_s32
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192
; LOWER: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sgt_to_sge_s32
; SELECT: liveins: $w0
; SELECT: %reg:gpr32sp = COPY $w0
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg, 2, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 8191
%cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: sgt_to_sge_s64
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; x sgt c => s sge c + 1
;
; log_2(8192) == 13, so we can represent this as a 12 bit value with a
; left shift.
; LOWER-LABEL: name: sgt_to_sge_s64
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192
; LOWER: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: sgt_to_sge_s64
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 2, 12, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 8191
%cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: no_opt_int32_min
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; The cmp should not change.
;
; If we subtract 1 from the constant, it will wrap around, and so it's not
; true that
;
; x slt c => x sle c - 1
; x sge c => x sgt c - 1
; LOWER-LABEL: name: no_opt_int32_min
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: %cst:_(s32) = G_CONSTANT i32 -2147483648
; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: no_opt_int32_min
; SELECT: liveins: $w0
; SELECT: %reg:gpr32 = COPY $w0
; SELECT: %cst:gpr32 = MOVi32imm -2147483648
; SELECT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg, %cst, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 -2147483648
%cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: no_opt_int64_min
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; The cmp should not change.
;
; If we subtract 1 from the constant, it will wrap around, and so it's not
; true that
;
; x slt c => x sle c - 1
; x sge c => x sgt c - 1
; LOWER-LABEL: name: no_opt_int64_min
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: %cst:_(s64) = G_CONSTANT i64 -9223372036854775808
; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: no_opt_int64_min
; SELECT: liveins: $x0
; SELECT: %reg:gpr64 = COPY $x0
; SELECT: %cst:gpr64 = MOVi64imm -9223372036854775808
; SELECT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr %reg, %cst, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 -9223372036854775808
%cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: no_opt_int32_max
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0
; The cmp should not change.
;
; If we add 1 to the constant, it will wrap around, and so it's not true
; that
;
; x slt c => x sle c - 1
; x sge c => x sgt c - 1
; LOWER-LABEL: name: no_opt_int32_max
; LOWER: liveins: $w0
; LOWER: %reg:_(s32) = COPY $w0
; LOWER: %cst:_(s32) = G_CONSTANT i32 2147483647
; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: no_opt_int32_max
; SELECT: liveins: $w0
; SELECT: %reg:gpr32 = COPY $w0
; SELECT: %cst:gpr32 = MOVi32imm 2147483647
; SELECT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg, %cst, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s32) = COPY $w0
%cst:_(s32) = G_CONSTANT i32 2147483647
%cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: no_opt_int64_max
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; The cmp should not change.
;
; If we add 1 to the constant, it will wrap around, and so it's not true
; that
;
; x slt c => x sle c - 1
; x sge c => x sgt c - 1
; LOWER-LABEL: name: no_opt_int64_max
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: %cst:_(s64) = G_CONSTANT i64 9223372036854775807
; LOWER: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: no_opt_int64_max
; SELECT: liveins: $x0
; SELECT: %reg:gpr64 = COPY $x0
; SELECT: %cst:gpr64 = MOVi64imm 9223372036854775807
; SELECT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr %reg, %cst, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 9223372036854775807
%cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: no_opt_zero
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; The cmp should not change during the lowering pass.
;
; This is an unsigned comparison, so when the constant is 0, the following
; does not hold:
;
; x slt c => x sle c - 1
; x sge c => x sgt c - 1
; LOWER-LABEL: name: no_opt_zero
; LOWER: liveins: $x0
; LOWER: %reg:_(s64) = COPY $x0
; LOWER: %cst:_(s64) = G_CONSTANT i64 0
; LOWER: %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: no_opt_zero
; SELECT: liveins: $x0
; SELECT: %reg:gpr64sp = COPY $x0
; SELECT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri %reg, 0, 0, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg:_(s64) = COPY $x0
%cst:_(s64) = G_CONSTANT i64 0
%cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0
...
---
name: cmp_and_select
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $w0, $w1
; The G_ICMP is optimized here to be a slt comparison by adding 1 to the
; constant. So, the CSELWr should use the predicate code 11, rather than
; 13.
; LOWER-LABEL: name: cmp_and_select
; LOWER: liveins: $w0, $w1
; LOWER: %reg0:_(s32) = COPY $w0
; LOWER: %reg1:_(s32) = COPY $w1
; LOWER: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; LOWER: %cmp:_(s32) = G_ICMP intpred(slt), %reg0(s32), [[C]]
; LOWER: %trunc:_(s1) = G_TRUNC %cmp(s32)
; LOWER: %select:_(s32) = G_SELECT %trunc(s1), %reg0, %reg1
; LOWER: $w0 = COPY %select(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: cmp_and_select
; SELECT: liveins: $w0, $w1
; SELECT: %reg0:gpr32common = COPY $w0
; SELECT: %reg1:gpr32 = COPY $w1
; SELECT: [[SUBSWri:%[0-9]+]]:gpr32 = SUBSWri %reg0, 0, 0, implicit-def $nzcv
; SELECT: %select:gpr32 = CSELWr %reg0, %reg1, 11, implicit $nzcv
; SELECT: $w0 = COPY %select
; SELECT: RET_ReallyLR implicit $w0
%reg0:_(s32) = COPY $w0
%reg1:_(s32) = COPY $w1
%cst:_(s32) = G_CONSTANT i32 -1
%cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst
%trunc:_(s1) = G_TRUNC %cmp(s32)
%select:_(s32) = G_SELECT %trunc(s1), %reg0, %reg1
$w0 = COPY %select(s32)
RET_ReallyLR implicit $w0
...
---
name: andsxri
legalized: true
tracksRegLiveness: true
body: |
bb.0:
liveins: $x0
; Show that we can select a tst/ands by optimizing the G_ICMP in the
; lowering phase.
; LOWER-LABEL: name: andsxri
; LOWER: liveins: $x0
; LOWER: %reg0:gpr(s64) = COPY $x0
; LOWER: %bit:gpr(s64) = G_CONSTANT i64 8
; LOWER: %and:gpr(s64) = G_AND %reg0, %bit
; LOWER: [[C:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 0
; LOWER: %cmp:gpr(s32) = G_ICMP intpred(sge), %and(s64), [[C]]
; LOWER: $w0 = COPY %cmp(s32)
; LOWER: RET_ReallyLR implicit $w0
; SELECT-LABEL: name: andsxri
; SELECT: liveins: $x0
; SELECT: %reg0:gpr64 = COPY $x0
; SELECT: [[ANDSXri:%[0-9]+]]:gpr64 = ANDSXri %reg0, 8000, implicit-def $nzcv
; SELECT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv
; SELECT: $w0 = COPY %cmp
; SELECT: RET_ReallyLR implicit $w0
%reg0:gpr(s64) = COPY $x0
%bit:gpr(s64) = G_CONSTANT i64 8
%and:gpr(s64) = G_AND %reg0, %bit
%cst:gpr(s64) = G_CONSTANT i64 -1
%cmp:gpr(s32) = G_ICMP intpred(sgt), %and(s64), %cst
$w0 = COPY %cmp(s32)
RET_ReallyLR implicit $w0