As far as I can tell treating s1 values as legal makes no sense. There are no allocatable 1-bit registers. SelectionDAG legalizes the usual set of boolean operations to 32-bits, and this should do the same. This avoids some special case handling in the selector of s1 values, and some extra code to look through truncates. This makes some code worse at -O0, since nothing cleans up the and 1 the artifact combiner inserts. We could probably add some non-essential combines or teach the artifact combiner to elide intermediates betweeen boolean uses and defs.
715 lines
23 KiB
YAML
715 lines
23 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -mtriple=aarch64-apple-darwin -run-pass=instruction-select -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s
|
|
|
|
...
|
|
---
|
|
name: select_f32
|
|
alignment: 4
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.0:
|
|
liveins: $s0, $s1, $w0
|
|
|
|
; CHECK-LABEL: name: select_f32
|
|
; CHECK: liveins: $s0, $s1, $w0
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $s0
|
|
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY $s1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
|
|
; CHECK-NEXT: [[FCSELSrrr:%[0-9]+]]:fpr32 = FCSELSrrr [[COPY1]], [[COPY2]], 1, implicit $nzcv
|
|
; CHECK-NEXT: $s0 = COPY [[FCSELSrrr]]
|
|
; CHECK-NEXT: RET_ReallyLR implicit $s0
|
|
%0:gpr(s32) = COPY $w0
|
|
%1:fpr(s32) = COPY $s0
|
|
%2:fpr(s32) = COPY $s1
|
|
%4:fpr(s32) = G_SELECT %0, %1, %2
|
|
$s0 = COPY %4(s32)
|
|
RET_ReallyLR implicit $s0
|
|
|
|
...
|
|
---
|
|
name: select_f64
|
|
alignment: 4
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.0:
|
|
liveins: $d0, $d1, $w0
|
|
|
|
; CHECK-LABEL: name: select_f64
|
|
; CHECK: liveins: $d0, $d1, $w0
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0
|
|
; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY $d1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri [[COPY]], 0, implicit-def $nzcv
|
|
; CHECK-NEXT: [[FCSELDrrr:%[0-9]+]]:fpr64 = FCSELDrrr [[COPY1]], [[COPY2]], 1, implicit $nzcv
|
|
; CHECK-NEXT: $d0 = COPY [[FCSELDrrr]]
|
|
; CHECK-NEXT: RET_ReallyLR implicit $d0
|
|
%0:gpr(s32) = COPY $w0
|
|
%1:fpr(s64) = COPY $d0
|
|
%2:fpr(s64) = COPY $d1
|
|
%4:fpr(s64) = G_SELECT %0, %1, %2
|
|
$d0 = COPY %4(s64)
|
|
RET_ReallyLR implicit $d0
|
|
...
|
|
---
|
|
name: csel
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2, $w3
|
|
; CHECK-LABEL: name: csel
|
|
; CHECK: liveins: $w0, $w1, $w2, $w3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w3
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSELWr %t, %f, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = COPY $w2
|
|
%f:gpr(s32) = COPY $w3
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinc_t_0_f_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1
|
|
; G_SELECT cc, 0, 1 -> CSINC zreg, zreg, cc
|
|
|
|
; CHECK-LABEL: name: csinc_t_0_f_1
|
|
; CHECK: liveins: $w0, $w1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr $wzr, $wzr, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = G_CONSTANT i32 0
|
|
%f:gpr(s32) = G_CONSTANT i32 1
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinv_t_0_f_neg_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1
|
|
; G_SELECT cc 0, -1 -> CSINV zreg, zreg cc
|
|
|
|
; CHECK-LABEL: name: csinv_t_0_f_neg_1
|
|
; CHECK: liveins: $w0, $w1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINVWr $wzr, $wzr, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = G_CONSTANT i32 0
|
|
%f:gpr(s32) = G_CONSTANT i32 -1
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinc_t_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
|
|
|
|
; CHECK-LABEL: name: csinc_t_1
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %f, $wzr, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = G_CONSTANT i32 1
|
|
%f:gpr(s32) = COPY $w2
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinv_t_neg_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, -1, f -> CSINV f, zreg, inv_cc
|
|
|
|
; CHECK-LABEL: name: csinv_t_neg_1
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINVWr %f, $wzr, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = G_CONSTANT i32 -1
|
|
%f:gpr(s32) = COPY $w2
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinc_f_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, t, 1 -> CSINC t, zreg, cc
|
|
|
|
; CHECK-LABEL: name: csinc_f_1
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %t, $wzr, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = COPY $w2
|
|
%f:gpr(s32) = G_CONSTANT i32 1
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinc_f_neg_1
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, t, -1 -> CSINC t, zreg, cc
|
|
|
|
; CHECK-LABEL: name: csinc_f_neg_1
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[SUBSWrr:%[0-9]+]]:gpr32 = SUBSWrr %reg0, %reg1, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINVWr %t, $wzr, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%cmp:gpr(s32) = G_ICMP intpred(ne), %reg0(s32), %reg1
|
|
%t:gpr(s32) = COPY $w2
|
|
%f:gpr(s32) = G_CONSTANT i32 -1
|
|
%select:gpr(s32) = G_SELECT %cmp, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinc_t_1_no_cmp
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1
|
|
; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
|
|
|
|
; CHECK-LABEL: name: csinc_t_1_no_cmp
|
|
; CHECK: liveins: $w0, $w1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %f, $wzr, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%t:gpr(s32) = G_CONSTANT i32 1
|
|
%f:gpr(s32) = COPY $w1
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinc_f_1_no_cmp
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1
|
|
; G_SELECT cc, t, 1 -> CSINC t, zreg, cc
|
|
|
|
; CHECK-LABEL: name: csinc_f_1_no_cmp
|
|
; CHECK: liveins: $w0, $w1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %t, $wzr, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%t:gpr(s32) = COPY $w1
|
|
%f:gpr(s32) = G_CONSTANT i32 1
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinc_t_1_no_cmp_s64
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
; G_SELECT cc, 1, f -> CSINC f, zreg, inv_cc
|
|
|
|
; CHECK-LABEL: name: csinc_t_1_no_cmp_s64
|
|
; CHECK: liveins: $x0, $x1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr64sp = COPY $x0
|
|
; CHECK-NEXT: %cond:gpr32common = COPY %reg0.sub_32
|
|
; CHECK-NEXT: %f:gpr64 = COPY $x1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %cond, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr64 = CSINCXr %f, $xzr, 0, implicit $nzcv
|
|
; CHECK-NEXT: $x0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $x0
|
|
%reg0:gpr(s64) = COPY $x0
|
|
%cond:gpr(s32) = G_TRUNC %reg0(s64)
|
|
%t:gpr(s64) = G_CONSTANT i64 1
|
|
%f:gpr(s64) = COPY $x1
|
|
%select:gpr(s64) = G_SELECT %cond, %t, %f
|
|
$x0 = COPY %select(s64)
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
name: csneg_s32
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
|
|
|
|
; CHECK-LABEL: name: csneg_s32
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSNEGWr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%t:gpr(s32) = COPY $w2
|
|
%zero:gpr(s32) = G_CONSTANT i32 0
|
|
%sub:gpr(s32) = G_SUB %zero(s32), %reg1
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %sub
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csneg_inverted_cc
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, (G_SUB 0, %x), %false -> CSNEG %x, %false, inv_cc
|
|
|
|
; CHECK-LABEL: name: csneg_inverted_cc
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSNEGWr %f, %reg1, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%f:gpr(s32) = COPY $w2
|
|
%zero:gpr(s32) = G_CONSTANT i32 0
|
|
%sub:gpr(s32) = G_SUB %zero(s32), %reg1
|
|
%select:gpr(s32) = G_SELECT %reg0, %sub, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csneg_s64
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1, $x2
|
|
; G_SELECT cc, true, (G_SUB 0, x) -> CSNEG true, x, cc
|
|
|
|
; CHECK-LABEL: name: csneg_s64
|
|
; CHECK: liveins: $x0, $x1, $x2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr64sp = COPY $x0
|
|
; CHECK-NEXT: %cond:gpr32common = COPY %reg0.sub_32
|
|
; CHECK-NEXT: %reg1:gpr64 = COPY $x1
|
|
; CHECK-NEXT: %t:gpr64 = COPY $x2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %cond, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr64 = CSNEGXr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $x0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $x0
|
|
%reg0:gpr(s64) = COPY $x0
|
|
%cond:gpr(s32) = G_TRUNC %reg0(s64)
|
|
%reg1:gpr(s64) = COPY $x1
|
|
%t:gpr(s64) = COPY $x2
|
|
%zero:gpr(s64) = G_CONSTANT i64 0
|
|
%sub:gpr(s64) = G_SUB %zero(s64), %reg1
|
|
%select:gpr(s64) = G_SELECT %cond, %t, %sub
|
|
$x0 = COPY %select(s64)
|
|
RET_ReallyLR implicit $x0
|
|
...
|
|
---
|
|
name: csneg_with_true_cst
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; We should prefer eliminating the G_SUB over eliminating the constant true
|
|
; value.
|
|
|
|
; CHECK-LABEL: name: csneg_with_true_cst
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %t:gpr32 = MOVi32imm 1
|
|
; CHECK-NEXT: %reg2:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSNEGWr %t, %reg2, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%t:gpr(s32) = G_CONSTANT i32 1
|
|
%zero:gpr(s32) = G_CONSTANT i32 0
|
|
%reg2:gpr(s32) = COPY $w2
|
|
%sub:gpr(s32) = G_SUB %zero(s32), %reg2
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %sub
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
...
|
|
---
|
|
name: csinv_s32
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
|
|
|
|
; CHECK-LABEL: name: csinv_s32
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINVWr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%t:gpr(s32) = COPY $w2
|
|
%negative_one:gpr(s32) = G_CONSTANT i32 -1
|
|
%xor:gpr(s32) = G_XOR %reg1(s32), %negative_one
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %xor
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinv_inverted_cc
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, (G_XOR x, -1), %false -> CSINV %x, %false, inv_cc
|
|
|
|
; CHECK-LABEL: name: csinv_inverted_cc
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINVWr %f, %reg1, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%f:gpr(s32) = COPY $w2
|
|
%negative_one:gpr(s32) = G_CONSTANT i32 -1
|
|
%xor:gpr(s32) = G_XOR %reg1(s32), %negative_one
|
|
%select:gpr(s32) = G_SELECT %reg0, %xor, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinv_s64
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1, $x2
|
|
; G_SELECT cc, true, (G_XOR x, -1) -> CSINV true, x, cc
|
|
|
|
; CHECK-LABEL: name: csinv_s64
|
|
; CHECK: liveins: $x0, $x1, $x2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr64sp = COPY $x0
|
|
; CHECK-NEXT: %reg1:gpr64 = COPY $x1
|
|
; CHECK-NEXT: %cond:gpr32common = COPY %reg0.sub_32
|
|
; CHECK-NEXT: %t:gpr64 = COPY $x2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %cond, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr64 = CSINVXr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $x0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $x0
|
|
%reg0:gpr(s64) = COPY $x0
|
|
%reg1:gpr(s64) = COPY $x1
|
|
%cond:gpr(s32) = G_TRUNC %reg0(s64)
|
|
%t:gpr(s64) = COPY $x2
|
|
%negative_one:gpr(s64) = G_CONSTANT i64 -1
|
|
%xor:gpr(s64) = G_XOR %reg1(s64), %negative_one
|
|
%select:gpr(s64) = G_SELECT %cond, %t, %xor
|
|
$x0 = COPY %select(s64)
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
name: xor_not_negative_one
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1, $x2
|
|
; zext(s32 -1) != s64 -1, so we can't fold it away.
|
|
|
|
; CHECK-LABEL: name: xor_not_negative_one
|
|
; CHECK: liveins: $x0, $x1, $x2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr64sp = COPY $x0
|
|
; CHECK-NEXT: %reg1:gpr64 = COPY $x1
|
|
; CHECK-NEXT: %cond:gpr32common = COPY %reg0.sub_32
|
|
; CHECK-NEXT: %t:gpr64 = COPY $x2
|
|
; CHECK-NEXT: %negative_one:gpr32 = MOVi32imm -1
|
|
; CHECK-NEXT: %zext:gpr64 = SUBREG_TO_REG 0, %negative_one, %subreg.sub_32
|
|
; CHECK-NEXT: %xor:gpr64 = EORXrr %reg1, %zext
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %cond, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr64 = CSELXr %t, %xor, 1, implicit $nzcv
|
|
; CHECK-NEXT: $x0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $x0
|
|
%reg0:gpr(s64) = COPY $x0
|
|
%reg1:gpr(s64) = COPY $x1
|
|
%cond:gpr(s32) = G_TRUNC %reg0(s64)
|
|
%t:gpr(s64) = COPY $x2
|
|
%negative_one:gpr(s32) = G_CONSTANT i32 -1
|
|
%zext:gpr(s64) = G_ZEXT %negative_one(s32)
|
|
%xor:gpr(s64) = G_XOR %reg1(s64), %zext
|
|
%select:gpr(s64) = G_SELECT %cond(s32), %t, %xor
|
|
$x0 = COPY %select(s64)
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
name: csinc_s32
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, %true, (G_ADD %x, 1) -> CSINC %true, %x, cc
|
|
; CHECK-LABEL: name: csinc_s32
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %t:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%t:gpr(s32) = COPY $w2
|
|
%one:gpr(s32) = G_CONSTANT i32 1
|
|
%add:gpr(s32) = G_ADD %reg1(s32), %one
|
|
%select:gpr(s32) = G_SELECT %reg0, %t, %add
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinc_s32_inverted_cc
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; G_SELECT cc, (G_ADD %x, 1), %false -> CSINC %x, %false, inv_cc
|
|
; CHECK-LABEL: name: csinc_s32_inverted_cc
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %f:gpr32 = COPY $w2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSINCWr %f, %reg1, 0, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%f:gpr(s32) = COPY $w2
|
|
%one:gpr(s32) = G_CONSTANT i32 1
|
|
%add:gpr(s32) = G_ADD %reg1(s32), %one
|
|
%select:gpr(s32) = G_SELECT %reg0, %add, %f
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|
|
|
|
...
|
|
---
|
|
name: csinc_ptr_add
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1, $x2
|
|
; G_SELECT cc, %true, (G_PTR_ADD %x, 1) -> CSINC %true, %x, cc
|
|
|
|
; CHECK-LABEL: name: csinc_ptr_add
|
|
; CHECK: liveins: $x0, $x1, $x2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr64sp = COPY $x0
|
|
; CHECK-NEXT: %reg1:gpr64 = COPY $x1
|
|
; CHECK-NEXT: %cond:gpr32common = COPY %reg0.sub_32
|
|
; CHECK-NEXT: %t:gpr64 = COPY $x2
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %cond, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr64 = CSINCXr %t, %reg1, 1, implicit $nzcv
|
|
; CHECK-NEXT: $x0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $x0
|
|
%reg0:gpr(s64) = COPY $x0
|
|
%reg1:gpr(p0) = COPY $x1
|
|
%cond:gpr(s32) = G_TRUNC %reg0(s64)
|
|
%t:gpr(p0) = COPY $x2
|
|
%one:gpr(s64) = G_CONSTANT i64 1
|
|
%ptr_add:gpr(p0) = G_PTR_ADD %reg1(p0), %one
|
|
%select:gpr(p0) = G_SELECT %cond(s32), %t, %ptr_add
|
|
$x0 = COPY %select(p0)
|
|
RET_ReallyLR implicit $x0
|
|
|
|
...
|
|
---
|
|
name: binop_dont_optimize_twice
|
|
legalized: true
|
|
regBankSelected: true
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $w0, $w1, $w2
|
|
; CHECK-LABEL: name: binop_dont_optimize_twice
|
|
; CHECK: liveins: $w0, $w1, $w2
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: %reg0:gpr32 = COPY $w0
|
|
; CHECK-NEXT: %reg1:gpr32 = COPY $w1
|
|
; CHECK-NEXT: %reg2:gpr32 = COPY $w2
|
|
; CHECK-NEXT: %xor:gpr32 = ORNWrr $wzr, %reg1
|
|
; CHECK-NEXT: [[ANDSWri:%[0-9]+]]:gpr32 = ANDSWri %reg0, 0, implicit-def $nzcv
|
|
; CHECK-NEXT: %select:gpr32 = CSNEGWr %xor, %reg2, 1, implicit $nzcv
|
|
; CHECK-NEXT: $w0 = COPY %select
|
|
; CHECK-NEXT: RET_ReallyLR implicit $w0
|
|
%reg0:gpr(s32) = COPY $w0
|
|
%reg1:gpr(s32) = COPY $w1
|
|
%reg2:gpr(s32) = COPY $w2
|
|
%f:gpr(s32) = COPY $w2
|
|
%negative_one:gpr(s32) = G_CONSTANT i32 -1
|
|
%xor:gpr(s32) = G_XOR %reg1(s32), %negative_one
|
|
%zero:gpr(s32) = G_CONSTANT i32 0
|
|
%sub:gpr(s32) = G_SUB %zero(s32), %reg2
|
|
%select:gpr(s32) = G_SELECT %reg0, %xor, %sub
|
|
$w0 = COPY %select(s32)
|
|
RET_ReallyLR implicit $w0
|