xref: /llvm-project/llvm/test/CodeGen/AArch64/cond-sel-value-prop.ll (revision adec9223616477df023026b0269ccd008701cc94)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
3
4; Transform "a == C ? C : x" to "a == C ? a : x" to avoid materializing C.
5define i32 @test1(i32 %x) {
6; CHECK-LABEL: test1:
7; CHECK:       // %bb.0:
8; CHECK-NEXT:    mov w8, #7
9; CHECK-NEXT:    cmp w0, #2
10; CHECK-NEXT:    csel w0, w0, w8, eq
11; CHECK-NEXT:    ret
12  %cmp = icmp eq i32 %x, 2
13  %res = select i1 %cmp, i32 2, i32 7
14  ret i32 %res
15}
16
17; Transform "a == C ? C : x" to "a == C ? a : x" to avoid materializing C.
18define i64 @test2(i64 %x) {
19; CHECK-LABEL: test2:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    mov w8, #7
22; CHECK-NEXT:    cmp x0, #2
23; CHECK-NEXT:    csel x0, x0, x8, eq
24; CHECK-NEXT:    ret
25  %cmp = icmp eq i64 %x, 2
26  %res = select i1 %cmp, i64 2, i64 7
27  ret i64 %res
28}
29
30; Transform "a != C ? x : C" to "a != C ? x : a" to avoid materializing C.
31define i64 @test3(i64 %x) {
32; CHECK-LABEL: test3:
33; CHECK:       // %bb.0:
34; CHECK-NEXT:    mov w8, #2
35; CHECK-NEXT:    cmp x0, #7
36; CHECK-NEXT:    csel x0, x8, x0, ne
37; CHECK-NEXT:    ret
38  %cmp = icmp ne i64 %x, 7
39  %res = select i1 %cmp, i64 2, i64 7
40  ret i64 %res
41}
42
43; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == 0.  If we did we
44; would needlessly extend the live range of x0 when we can just use xzr.
45define i64 @test4(i64 %x) {
46; CHECK-LABEL: test4:
47; CHECK:       // %bb.0:
48; CHECK-NEXT:    mov w8, #7
49; CHECK-NEXT:    cmp x0, #0
50; CHECK-NEXT:    csel x0, xzr, x8, eq
51; CHECK-NEXT:    ret
52  %cmp = icmp eq i64 %x, 0
53  %res = select i1 %cmp, i64 0, i64 7
54  ret i64 %res
55}
56
57; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == 1.  If we did we
58; would needlessly extend the live range of x0 when we can just use xzr with
59; CSINC to materialize the 1.
60define i64 @test5(i64 %x) {
61; CHECK-LABEL: test5:
62; CHECK:       // %bb.0:
63; CHECK-NEXT:    mov w8, #7
64; CHECK-NEXT:    cmp x0, #1
65; CHECK-NEXT:    csinc x0, x8, xzr, ne
66; CHECK-NEXT:    ret
67  %cmp = icmp eq i64 %x, 1
68  %res = select i1 %cmp, i64 1, i64 7
69  ret i64 %res
70}
71
72; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == -1.  If we did we
73; would needlessly extend the live range of x0 when we can just use xzr with
74; CSINV to materialize the -1.
75define i64 @test6(i64 %x) {
76; CHECK-LABEL: test6:
77; CHECK:       // %bb.0:
78; CHECK-NEXT:    mov w8, #7
79; CHECK-NEXT:    cmn x0, #1
80; CHECK-NEXT:    csinv x0, x8, xzr, ne
81; CHECK-NEXT:    ret
82  %cmp = icmp eq i64 %x, -1
83  %res = select i1 %cmp, i64 -1, i64 7
84  ret i64 %res
85}
86
87define i64 @test7(i64 %x) {
88; CHECK-LABEL: test7:
89; CHECK:       // %bb.0:
90; CHECK-NEXT:    cmp x0, #7
91; CHECK-NEXT:    csinc x0, x0, xzr, eq
92; CHECK-NEXT:    ret
93  %cmp = icmp eq i64 %x, 7
94  %res = select i1 %cmp, i64 7, i64 1
95  ret i64 %res
96}
97
98define i64 @test8(i64 %x) {
99; CHECK-LABEL: test8:
100; CHECK:       // %bb.0:
101; CHECK-NEXT:    cmp x0, #7
102; CHECK-NEXT:    csinc x0, x0, xzr, eq
103; CHECK-NEXT:    ret
104  %cmp = icmp ne i64 %x, 7
105  %res = select i1 %cmp, i64 1, i64 7
106  ret i64 %res
107}
108
109define i64 @test9(i64 %x) {
110; CHECK-LABEL: test9:
111; CHECK:       // %bb.0:
112; CHECK-NEXT:    cmp x0, #7
113; CHECK-NEXT:    csinv x0, x0, xzr, eq
114; CHECK-NEXT:    ret
115  %cmp = icmp eq i64 %x, 7
116  %res = select i1 %cmp, i64 7, i64 -1
117  ret i64 %res
118}
119
120; Rather than use a CNEG, use a CSINV to transform "a == 1 ? 1 : -1" to
121; "a == 1 ? a : -1" to avoid materializing a constant.
122define i32 @test10(i32 %x) {
123; CHECK-LABEL: test10:
124; CHECK:       // %bb.0:
125; CHECK-NEXT:    cmp w0, #1
126; CHECK-NEXT:    csinv w0, w0, wzr, eq
127; CHECK-NEXT:    ret
128  %cmp = icmp eq i32 %x, 1
129  %res = select i1 %cmp, i32 1, i32 -1
130  ret i32 %res
131}
132