1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2# RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s 3--- | 4 declare void @foo() 5 define void @self() { ret void } 6 define void @self_with_copy() { ret void } 7 define void @self_not_equivalent_overwrite_w0() { ret void } 8 define void @self_not_equivalent_overwrite_w0_implicit() { ret void } 9 define void @self_not_equivalent_different_copies() { ret void } 10 define void @self_with_assert_zext() { ret void } 11... 12--- 13name: self 14tracksRegLiveness: true 15body: | 16 bb.0: 17 liveins: $w0, $w1 18 ; Optimize (cond ? %a : %a) -> %a 19 ; CHECK-LABEL: name: self 20 ; CHECK: liveins: $w0, $w1 21 ; CHECK: %a:_(s32) = COPY $w0 22 ; CHECK: $w0 = COPY %a(s32) 23 ; CHECK: RET_ReallyLR implicit $w0 24 %a:_(s32) = COPY $w0 25 %cond_wide:gpr(s32) = COPY $w1 26 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 27 %select:_(s32) = G_SELECT %cond(s1), %a, %a 28 $w0 = COPY %select(s32) 29 RET_ReallyLR implicit $w0 30 31... 32--- 33name: self_with_copy 34tracksRegLiveness: true 35body: | 36 bb.0: 37 liveins: $w0, $w1 38 ; Optimize (cond ? %a : %b) -> %a 39 ; 40 ; This shows that we are looking through copies correctly and deduce that 41 ; %b is a copy from %a. 42 ; 43 ; CHECK-LABEL: name: self_with_copy 44 ; CHECK: liveins: $w0, $w1 45 ; CHECK: %a:_(s32) = COPY $w0 46 ; CHECK: $w0 = COPY %a(s32) 47 ; CHECK: RET_ReallyLR implicit $w0 48 %a:_(s32) = COPY $w0 49 %b:_(s32) = COPY %a 50 %cond_wide:gpr(s32) = COPY $w1 51 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 52 %select:_(s32) = G_SELECT %cond(s1), %a, %b 53 $w0 = COPY %select(s32) 54 RET_ReallyLR implicit $w0 55 56... 57--- 58name: self_not_equivalent_overwrite_w0 59tracksRegLiveness: true 60body: | 61 bb.0: 62 liveins: $w0, $w1 63 ; 64 ; $w0 is overwritten by a copy from $w1, so the copies for %a and %b are 65 ; not the same. 66 ; 67 ; CHECK-LABEL: name: self_not_equivalent_overwrite_w0 68 ; CHECK: liveins: $w0, $w1 69 ; CHECK: %a:_(s32) = COPY $w0 70 ; CHECK: $w0 = COPY $w1 71 ; CHECK: %b:_(s32) = COPY $w0 72 ; CHECK: %cond_wide:gpr(s32) = COPY $w1 73 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 74 ; CHECK: %select:_(s32) = G_SELECT %cond(s1), %a, %b 75 ; CHECK: $w0 = COPY %select(s32) 76 ; CHECK: RET_ReallyLR implicit $w0 77 %a:_(s32) = COPY $w0 78 $w0 = COPY $w1 79 %b:_(s32) = COPY $w0 80 %cond_wide:gpr(s32) = COPY $w1 81 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 82 %select:_(s32) = G_SELECT %cond(s1), %a, %b 83 $w0 = COPY %select(s32) 84 RET_ReallyLR implicit $w0 85 86... 87--- 88name: self_not_equivalent_overwrite_w0_implicit 89tracksRegLiveness: true 90body: | 91 bb.0: 92 liveins: $w0, $w1 93 ; 94 ; $w0 is overwritten by a call which defines it implicitly, so the copies 95 ; are not the same. 96 ; 97 ; CHECK-LABEL: name: self_not_equivalent_overwrite_w0_implicit 98 ; CHECK: liveins: $w0, $w1 99 ; CHECK: %a:_(s32) = COPY $w0 100 ; CHECK: BL @foo, implicit-def $w0 101 ; CHECK: %b:_(s32) = COPY $w0 102 ; CHECK: %cond_wide:gpr(s32) = COPY $w1 103 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 104 ; CHECK: %select:_(s32) = G_SELECT %cond(s1), %a, %b 105 ; CHECK: $w0 = COPY %select(s32) 106 ; CHECK: RET_ReallyLR implicit $w0 107 %a:_(s32) = COPY $w0 108 BL @foo, implicit-def $w0 109 %b:_(s32) = COPY $w0 110 %cond_wide:gpr(s32) = COPY $w1 111 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 112 %select:_(s32) = G_SELECT %cond(s1), %a, %b 113 $w0 = COPY %select(s32) 114 RET_ReallyLR implicit $w0 115 116... 117--- 118name: self_not_equivalent_different_copies 119tracksRegLiveness: true 120body: | 121 bb.0: 122 liveins: $w0, $w1 123 ; In this case, the copies are not equivalent, so there is no optimization. 124 ; 125 ; CHECK-LABEL: name: self_not_equivalent_different_copies 126 ; CHECK: liveins: $w0, $w1 127 ; CHECK: %a:_(s32) = COPY $w0 128 ; CHECK: %b:_(s32) = COPY $w1 129 ; CHECK: %cond_wide:gpr(s32) = COPY $w1 130 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 131 ; CHECK: %select:_(s32) = G_SELECT %cond(s1), %a, %b 132 ; CHECK: $w0 = COPY %select(s32) 133 ; CHECK: RET_ReallyLR implicit $w0 134 %a:_(s32) = COPY $w0 135 %b:_(s32) = COPY $w1 136 %c:_(s32) = COPY %b 137 %cond_wide:gpr(s32) = COPY $w1 138 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 139 %select:_(s32) = G_SELECT %cond(s1), %a, %c 140 $w0 = COPY %select(s32) 141 RET_ReallyLR implicit $w0 142 143... 144--- 145name: self_with_assert_zext 146tracksRegLiveness: true 147body: | 148 bb.0: 149 liveins: $w0, $w1 150 ; We should walk through G_ASSERT_ZEXT as if it's a copy, and remove the 151 ; G_SELECT. 152 ; 153 ; CHECK-LABEL: name: self_with_assert_zext 154 ; CHECK: liveins: $w0, $w1 155 ; CHECK: %a:_(s32) = COPY $w0 156 ; CHECK: %a_assert_zext:_(s32) = G_ASSERT_ZEXT %a, 16 157 ; CHECK: $w0 = COPY %a_assert_zext(s32) 158 ; CHECK: RET_ReallyLR implicit $w0 159 %a:_(s32) = COPY $w0 160 %a_assert_zext:_(s32) = G_ASSERT_ZEXT %a, 16 161 %b:_(s32) = COPY %a_assert_zext 162 %cond_wide:gpr(s32) = COPY $w1 163 %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 164 %select:_(s32) = G_SELECT %cond(s1), %a_assert_zext, %b 165 $w0 = COPY %select(s32) 166 RET_ReallyLR implicit $w0 167