1; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s 2 3; Transform "a == C ? C : x" to "a == C ? a : x" to avoid materializing C. 4; CHECK-LABEL: test1: 5; CHECK: cmp w[[REG1:[0-9]+]], #2 6; CHECK: orr w[[REG2:[0-9]+]], wzr, #0x7 7; CHECK: csel w0, w[[REG1]], w[[REG2]], eq 8define i32 @test1(i32 %x) { 9 %cmp = icmp eq i32 %x, 2 10 %res = select i1 %cmp, i32 2, i32 7 11 ret i32 %res 12} 13 14; Transform "a == C ? C : x" to "a == C ? a : x" to avoid materializing C. 15; CHECK-LABEL: test2: 16; CHECK: cmp x[[REG1:[0-9]+]], #2 17; CHECK: orr w[[REG2:[0-9]+]], wzr, #0x7 18; CHECK: csel x0, x[[REG1]], x[[REG2]], eq 19define i64 @test2(i64 %x) { 20 %cmp = icmp eq i64 %x, 2 21 %res = select i1 %cmp, i64 2, i64 7 22 ret i64 %res 23} 24 25; Transform "a != C ? x : C" to "a != C ? x : a" to avoid materializing C. 26; CHECK-LABEL: test3: 27; CHECK: cmp x[[REG1:[0-9]+]], #7 28; CHECK: orr w[[REG2:[0-9]+]], wzr, #0x2 29; CHECK: csel x0, x[[REG2]], x[[REG1]], ne 30define i64 @test3(i64 %x) { 31 %cmp = icmp ne i64 %x, 7 32 %res = select i1 %cmp, i64 2, i64 7 33 ret i64 %res 34} 35 36; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == 0. If we did we 37; would needlessly extend the live range of x0 when we can just use xzr. 38; CHECK-LABEL: test4: 39; CHECK: cmp x0, #0 40; CHECK: orr w8, wzr, #0x7 41; CHECK: csel x0, xzr, x8, eq 42define i64 @test4(i64 %x) { 43 %cmp = icmp eq i64 %x, 0 44 %res = select i1 %cmp, i64 0, i64 7 45 ret i64 %res 46} 47 48; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == 1. If we did we 49; would needlessly extend the live range of x0 when we can just use xzr with 50; CSINC to materialize the 1. 51; CHECK-LABEL: test5: 52; CHECK: cmp x0, #1 53; CHECK: orr w[[REG:[0-9]+]], wzr, #0x7 54; CHECK: csinc x0, x[[REG]], xzr, ne 55define i64 @test5(i64 %x) { 56 %cmp = icmp eq i64 %x, 1 57 %res = select i1 %cmp, i64 1, i64 7 58 ret i64 %res 59} 60 61; Don't transform "a == C ? C : x" to "a == C ? a : x" if a == -1. If we did we 62; would needlessly extend the live range of x0 when we can just use xzr with 63; CSINV to materialize the -1. 64; CHECK-LABEL: test6: 65; CHECK: cmn x0, #1 66; CHECK: orr w[[REG:[0-9]+]], wzr, #0x7 67; CHECK: csinv x0, x[[REG]], xzr, ne 68define i64 @test6(i64 %x) { 69 %cmp = icmp eq i64 %x, -1 70 %res = select i1 %cmp, i64 -1, i64 7 71 ret i64 %res 72} 73 74; CHECK-LABEL: test7: 75; CHECK: cmp x[[REG:[0-9]]], #7 76; CHECK: csinc x0, x[[REG]], xzr, eq 77define i64 @test7(i64 %x) { 78 %cmp = icmp eq i64 %x, 7 79 %res = select i1 %cmp, i64 7, i64 1 80 ret i64 %res 81} 82 83; CHECK-LABEL: test8: 84; CHECK: cmp x[[REG:[0-9]]], #7 85; CHECK: csinc x0, x[[REG]], xzr, eq 86define i64 @test8(i64 %x) { 87 %cmp = icmp ne i64 %x, 7 88 %res = select i1 %cmp, i64 1, i64 7 89 ret i64 %res 90} 91 92; CHECK-LABEL: test9: 93; CHECK: cmp x[[REG:[0-9]]], #7 94; CHECK: csinv x0, x[[REG]], xzr, eq 95define i64 @test9(i64 %x) { 96 %cmp = icmp eq i64 %x, 7 97 %res = select i1 %cmp, i64 7, i64 -1 98 ret i64 %res 99} 100 101; Rather than use a CNEG, use a CSINV to transform "a == 1 ? 1 : -1" to 102; "a == 1 ? a : -1" to avoid materializing a constant. 103; CHECK-LABEL: test10: 104; CHECK: cmp w[[REG:[0-9]]], #1 105; CHECK: csinv w0, w[[REG]], wzr, eq 106define i32 @test10(i32 %x) { 107 %cmp = icmp eq i32 %x, 1 108 %res = select i1 %cmp, i32 1, i32 -1 109 ret i32 %res 110} 111