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 8 define 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 19 define 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 30 define 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 42 define 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 55 define 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 68 define 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 77 define 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 86 define 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 95 define 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 106 define 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