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