1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2# RUN: llc -O0 -mtriple arm64-- -run-pass=regbankselect %s -o - | FileCheck %s 3 4# Check that we correctly assign register banks based off of instructions which 5# only use or only define FPRs. 6# 7# For example, G_SITOFP takes in a GPR, but only ever produces values on FPRs. 8# Some instructions can have inputs/outputs on either FPRs or GPRs. If one of 9# those instructions takes in the result of a G_SITOFP as a source, we should 10# put that source on a FPR. 11# 12# Similarly, G_FPTOSI can only take in a value on a FPR. So, if the result of 13# an instruction is consumed by a G_FPTOSI, we should put the instruction on 14# FPRs. 15 16--- 17name: load_only_uses_fp 18legalized: true 19tracksRegLiveness: true 20body: | 21 bb.0: 22 liveins: $x0 23 ; CHECK-LABEL: name: load_only_uses_fp 24 ; CHECK: liveins: $x0 25 ; CHECK: [[COPY:%[0-9]+]]:gpr(p0) = COPY $x0 26 ; CHECK: [[C:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 2.000000e+00 27 ; CHECK: [[LOAD:%[0-9]+]]:fpr(s32) = G_LOAD [[COPY]](p0) :: (load 4) 28 ; CHECK: [[FCMP:%[0-9]+]]:gpr(s32) = G_FCMP floatpred(uno), [[C]](s32), [[LOAD]] 29 ; CHECK: $w0 = COPY [[FCMP]](s32) 30 ; CHECK: RET_ReallyLR implicit $w0 31 %0:_(p0) = COPY $x0 32 %1:_(s32) = G_FCONSTANT float 2.0 33 %2:_(s32) = G_LOAD %0 :: (load 4) 34 %3:_(s32) = G_FCMP floatpred(uno), %1, %2 35 $w0 = COPY %3(s32) 36 RET_ReallyLR implicit $w0 37... 38--- 39name: unmerge_only_uses_fp 40 41legalized: true 42tracksRegLiveness: true 43body: | 44 bb.0: 45 liveins: $x0 46 ; CHECK-LABEL: name: unmerge_only_uses_fp 47 ; CHECK: liveins: $x0 48 ; CHECK: [[COPY:%[0-9]+]]:gpr(s64) = COPY $x0 49 ; CHECK: [[COPY1:%[0-9]+]]:fpr(s64) = COPY [[COPY]](s64) 50 ; CHECK: [[UV:%[0-9]+]]:fpr(s32), [[UV1:%[0-9]+]]:fpr(s32) = G_UNMERGE_VALUES [[COPY1]](s64) 51 ; CHECK: [[FCMP:%[0-9]+]]:gpr(s32) = G_FCMP floatpred(uno), [[UV]](s32), [[UV1]] 52 ; CHECK: $w0 = COPY [[FCMP]](s32) 53 ; CHECK: RET_ReallyLR implicit $w0 54 %0:_(s64) = COPY $x0 55 %1:_(s32), %2:_(s32) = G_UNMERGE_VALUES %0(s64) 56 %3:_(s32) = G_FCMP floatpred(uno), %1, %2 57 $w0 = COPY %3(s32) 58 RET_ReallyLR implicit $w0 59 60... 61--- 62name: store_defined_by_fp 63legalized: true 64tracksRegLiveness: true 65body: | 66 bb.0: 67 liveins: $x0, $w1 68 ; CHECK-LABEL: name: store_defined_by_fp 69 ; CHECK: liveins: $x0, $w1 70 ; CHECK: [[COPY:%[0-9]+]]:gpr(p0) = COPY $x0 71 ; CHECK: [[COPY1:%[0-9]+]]:gpr(s32) = COPY $w1 72 ; CHECK: [[SITOFP:%[0-9]+]]:fpr(s32) = G_SITOFP [[COPY1]](s32) 73 ; CHECK: G_STORE [[SITOFP]](s32), [[COPY]](p0) :: (store 4) 74 %0:_(p0) = COPY $x0 75 %1:_(s32) = COPY $w1 76 %2:_(s32) = G_SITOFP %1 77 G_STORE %2, %0 :: (store 4) 78 79... 80--- 81name: select_defined_by_fp_using_fp 82legalized: true 83tracksRegLiveness: true 84body: | 85 bb.0: 86 liveins: $w0, $w1, $w2 87 ; CHECK-LABEL: name: select_defined_by_fp_using_fp 88 ; CHECK: liveins: $w0, $w1, $w2 89 ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0 90 ; CHECK: [[TRUNC:%[0-9]+]]:gpr(s1) = G_TRUNC %2(s32) 91 ; CHECK: [[COPY1:%[0-9]+]]:gpr(s32) = COPY $w1 92 ; CHECK: [[COPY2:%[0-9]+]]:gpr(s32) = COPY $w2 93 ; CHECK: [[SITOFP:%[0-9]+]]:fpr(s32) = G_SITOFP [[COPY1]](s32) 94 ; CHECK: [[COPY3:%[0-9]+]]:fpr(s32) = COPY [[COPY2]](s32) 95 ; CHECK: [[SELECT:%[0-9]+]]:fpr(s32) = G_SELECT [[TRUNC]](s1), [[COPY3]], [[SITOFP]] 96 ; CHECK: [[FPTOSI:%[0-9]+]]:gpr(s32) = G_FPTOSI [[SELECT]](s32) 97 %0:_(s32) = COPY $w0 98 %1:_(s1) = G_TRUNC %3(s32) 99 %2:_(s32) = COPY $w1 100 %3:_(s32) = COPY $w2 101 %4:_(s32) = G_SITOFP %2 102 %6:_(s32) = G_SELECT %1(s1), %3, %4 103 %8:_(s32) = G_FPTOSI %6 104 105... 106--- 107name: load_used_by_phi_fpr 108legalized: true 109tracksRegLiveness: true 110body: | 111 ; CHECK-LABEL: name: load_used_by_phi_fpr 112 ; CHECK: bb.0: 113 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 114 ; CHECK: liveins: $x0, $s0, $s1, $w0, $w1 115 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 116 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 117 ; CHECK: %fpr_copy:fpr(s32) = COPY $s0 118 ; CHECK: %ptr:gpr(p0) = COPY $x0 119 ; CHECK: G_BRCOND %cond(s1), %bb.1 120 ; CHECK: G_BR %bb.2 121 ; CHECK: bb.1: 122 ; CHECK: successors: %bb.2(0x80000000) 123 ; CHECK: %load:fpr(s32) = G_LOAD %ptr(p0) :: (load 4) 124 ; CHECK: G_BR %bb.2 125 ; CHECK: bb.2: 126 ; CHECK: %phi:fpr(s32) = G_PHI %fpr_copy(s32), %bb.0, %load(s32), %bb.1 127 ; CHECK: $s0 = COPY %phi(s32) 128 ; CHECK: RET_ReallyLR implicit $s0 129 bb.0: 130 successors: %bb.1(0x40000000), %bb.2(0x40000000) 131 liveins: $x0, $s0, $s1, $w0, $w1 132 %cond_wide:_(s32) = COPY $w0 133 %cond:_(s1) = G_TRUNC %cond_wide(s32) 134 %fpr_copy:_(s32) = COPY $s0 135 %ptr:_(p0) = COPY $x0 136 G_BRCOND %cond(s1), %bb.1 137 G_BR %bb.2 138 bb.1: 139 successors: %bb.2 140 %load:_(s32) = G_LOAD %ptr(p0) :: (load 4) 141 G_BR %bb.2 142 bb.2: 143 %phi:_(s32) = G_PHI %fpr_copy(s32), %bb.0, %load(s32), %bb.1 144 $s0 = COPY %phi(s32) 145 RET_ReallyLR implicit $s0 146 147... 148--- 149name: load_used_by_phi_gpr 150legalized: true 151tracksRegLiveness: true 152body: | 153 ; CHECK-LABEL: name: load_used_by_phi_gpr 154 ; CHECK: bb.0: 155 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 156 ; CHECK: liveins: $x0, $s0, $s1, $w0, $w1 157 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 158 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 159 ; CHECK: %gpr_copy:gpr(s32) = COPY $w1 160 ; CHECK: %ptr:gpr(p0) = COPY $x0 161 ; CHECK: G_BRCOND %cond(s1), %bb.1 162 ; CHECK: G_BR %bb.2 163 ; CHECK: bb.1: 164 ; CHECK: successors: %bb.2(0x80000000) 165 ; CHECK: %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) 166 ; CHECK: G_BR %bb.2 167 ; CHECK: bb.2: 168 ; CHECK: %phi:gpr(s32) = G_PHI %gpr_copy(s32), %bb.0, %load(s32), %bb.1 169 ; CHECK: $s0 = COPY %phi(s32) 170 ; CHECK: RET_ReallyLR implicit $s0 171 bb.0: 172 successors: %bb.1(0x40000000), %bb.2(0x40000000) 173 liveins: $x0, $s0, $s1, $w0, $w1 174 %cond_wide:_(s32) = COPY $w0 175 %cond:_(s1) = G_TRUNC %cond_wide(s32) 176 %gpr_copy:_(s32) = COPY $w1 177 %ptr:_(p0) = COPY $x0 178 G_BRCOND %cond(s1), %bb.1 179 G_BR %bb.2 180 bb.1: 181 successors: %bb.2 182 %load:_(s32) = G_LOAD %ptr(p0) :: (load 4) 183 G_BR %bb.2 184 bb.2: 185 %phi:_(s32) = G_PHI %gpr_copy(s32), %bb.0, %load(s32), %bb.1 186 $s0 = COPY %phi(s32) 187 RET_ReallyLR implicit $s0 188 189... 190--- 191name: select_used_by_phi_fpr 192legalized: true 193tracksRegLiveness: true 194body: | 195 ; CHECK-LABEL: name: select_used_by_phi_fpr 196 ; CHECK: bb.0: 197 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 198 ; CHECK: liveins: $s0, $s1, $w0, $w1 199 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 200 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 201 ; CHECK: %fpr_copy:fpr(s32) = COPY $s0 202 ; CHECK: %gpr_copy:gpr(s32) = COPY $w1 203 ; CHECK: G_BRCOND %cond(s1), %bb.1 204 ; CHECK: G_BR %bb.2 205 ; CHECK: bb.1: 206 ; CHECK: successors: %bb.2(0x80000000) 207 ; CHECK: [[COPY:%[0-9]+]]:fpr(s32) = COPY %gpr_copy(s32) 208 ; CHECK: %select:fpr(s32) = G_SELECT %cond(s1), %fpr_copy, [[COPY]] 209 ; CHECK: G_BR %bb.2 210 ; CHECK: bb.2: 211 ; CHECK: %phi:fpr(s32) = G_PHI %fpr_copy(s32), %bb.0, %select(s32), %bb.1 212 ; CHECK: $w0 = COPY %phi(s32) 213 ; CHECK: RET_ReallyLR implicit $w0 214 ; The G_SELECT and G_PHI should end up with the same register bank. 215 ; 216 bb.0: 217 successors: %bb.1(0x40000000), %bb.2(0x40000000) 218 liveins: $s0, $s1, $w0, $w1 219 %cond_wide:_(s32) = COPY $w0 220 %cond:_(s1) = G_TRUNC %cond_wide(s32) 221 %fpr_copy:_(s32) = COPY $s0 222 %gpr_copy:_(s32) = COPY $w1 223 G_BRCOND %cond(s1), %bb.1 224 G_BR %bb.2 225 bb.1: 226 successors: %bb.2 227 %select:_(s32) = G_SELECT %cond(s1), %fpr_copy, %gpr_copy 228 G_BR %bb.2 229 bb.2: 230 %phi:_(s32) = G_PHI %fpr_copy(s32), %bb.0, %select(s32), %bb.1 231 $w0 = COPY %phi(s32) 232 RET_ReallyLR implicit $w0 233 234... 235--- 236name: select_used_by_phi_gpr 237legalized: true 238tracksRegLiveness: true 239body: | 240 ; CHECK-LABEL: name: select_used_by_phi_gpr 241 ; CHECK: bb.0: 242 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 243 ; CHECK: liveins: $s0, $s1, $w0, $w1 244 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 245 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 246 ; CHECK: %fpr_copy:fpr(s32) = COPY $s0 247 ; CHECK: %gpr_copy:gpr(s32) = COPY $w1 248 ; CHECK: G_BRCOND %cond(s1), %bb.1 249 ; CHECK: G_BR %bb.2 250 ; CHECK: bb.1: 251 ; CHECK: successors: %bb.2(0x80000000) 252 ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY %fpr_copy(s32) 253 ; CHECK: %select:gpr(s32) = G_SELECT %cond(s1), [[COPY]], %gpr_copy 254 ; CHECK: G_BR %bb.2 255 ; CHECK: bb.2: 256 ; CHECK: %phi:gpr(s32) = G_PHI %gpr_copy(s32), %bb.0, %select(s32), %bb.1 257 ; CHECK: $s0 = COPY %phi(s32) 258 ; CHECK: RET_ReallyLR implicit $s0 259 ; The G_SELECT and G_PHI should end up with the same register bank. 260 ; 261 bb.0: 262 successors: %bb.1(0x40000000), %bb.2(0x40000000) 263 liveins: $s0, $s1, $w0, $w1 264 %cond_wide:_(s32) = COPY $w0 265 %cond:_(s1) = G_TRUNC %cond_wide(s32) 266 %fpr_copy:_(s32) = COPY $s0 267 %gpr_copy:_(s32) = COPY $w1 268 G_BRCOND %cond(s1), %bb.1 269 G_BR %bb.2 270 bb.1: 271 successors: %bb.2 272 %select:_(s32) = G_SELECT %cond(s1), %fpr_copy, %gpr_copy 273 G_BR %bb.2 274 bb.2: 275 %phi:_(s32) = G_PHI %gpr_copy(s32), %bb.0, %select(s32), %bb.1 276 $s0 = COPY %phi(s32) 277 RET_ReallyLR implicit $s0 278 279 280... 281--- 282name: unmerge_used_by_phi_fpr 283legalized: true 284tracksRegLiveness: true 285body: | 286 ; CHECK-LABEL: name: unmerge_used_by_phi_fpr 287 ; CHECK: bb.0: 288 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 289 ; CHECK: liveins: $x0, $s0, $s1, $w0, $w1 290 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 291 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 292 ; CHECK: %fpr_copy:fpr(s32) = COPY $s0 293 ; CHECK: %unmerge_src:gpr(s64) = COPY $x0 294 ; CHECK: G_BRCOND %cond(s1), %bb.1 295 ; CHECK: G_BR %bb.2 296 ; CHECK: bb.1: 297 ; CHECK: successors: %bb.2(0x80000000) 298 ; CHECK: [[COPY:%[0-9]+]]:fpr(s64) = COPY %unmerge_src(s64) 299 ; CHECK: %unmerge_1:fpr(s32), %unmerge_2:fpr(s32) = G_UNMERGE_VALUES [[COPY]](s64) 300 ; CHECK: G_BR %bb.2 301 ; CHECK: bb.2: 302 ; CHECK: %phi:fpr(s32) = G_PHI %fpr_copy(s32), %bb.0, %unmerge_1(s32), %bb.1 303 ; CHECK: $s0 = COPY %phi(s32) 304 ; CHECK: RET_ReallyLR implicit $s0 305 bb.0: 306 successors: %bb.1(0x40000000), %bb.2(0x40000000) 307 liveins: $x0, $s0, $s1, $w0, $w1 308 %cond_wide:_(s32) = COPY $w0 309 %cond:_(s1) = G_TRUNC %cond_wide(s32) 310 %fpr_copy:_(s32) = COPY $s0 311 %unmerge_src:_(s64) = COPY $x0 312 G_BRCOND %cond(s1), %bb.1 313 G_BR %bb.2 314 bb.1: 315 successors: %bb.2 316 %unmerge_1:_(s32), %unmerge_2:_(s32) = G_UNMERGE_VALUES %unmerge_src(s64) 317 G_BR %bb.2 318 bb.2: 319 %phi:_(s32) = G_PHI %fpr_copy(s32), %bb.0, %unmerge_1(s32), %bb.1 320 $s0 = COPY %phi(s32) 321 RET_ReallyLR implicit $s0 322 323... 324--- 325name: unmerge_used_by_phi_gpr 326legalized: true 327tracksRegLiveness: true 328body: | 329 ; CHECK-LABEL: name: unmerge_used_by_phi_gpr 330 ; CHECK: bb.0: 331 ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) 332 ; CHECK: liveins: $x0, $s0, $s1, $w0, $w1 333 ; CHECK: %cond_wide:gpr(s32) = COPY $w0 334 ; CHECK: %cond:gpr(s1) = G_TRUNC %cond_wide(s32) 335 ; CHECK: %gpr_copy:gpr(s32) = COPY $w1 336 ; CHECK: %unmerge_src:gpr(s64) = COPY $x0 337 ; CHECK: G_BRCOND %cond(s1), %bb.1 338 ; CHECK: G_BR %bb.2 339 ; CHECK: bb.1: 340 ; CHECK: successors: %bb.2(0x80000000) 341 ; CHECK: %unmerge_1:gpr(s32), %unmerge_2:gpr(s32) = G_UNMERGE_VALUES %unmerge_src(s64) 342 ; CHECK: G_BR %bb.2 343 ; CHECK: bb.2: 344 ; CHECK: %phi:gpr(s32) = G_PHI %gpr_copy(s32), %bb.0, %unmerge_1(s32), %bb.1 345 ; CHECK: $s0 = COPY %phi(s32) 346 ; CHECK: RET_ReallyLR implicit $s0 347 bb.0: 348 successors: %bb.1(0x40000000), %bb.2(0x40000000) 349 liveins: $x0, $s0, $s1, $w0, $w1 350 %cond_wide:_(s32) = COPY $w0 351 %cond:_(s1) = G_TRUNC %cond_wide(s32) 352 %gpr_copy:_(s32) = COPY $w1 353 %unmerge_src:_(s64) = COPY $x0 354 G_BRCOND %cond(s1), %bb.1 355 G_BR %bb.2 356 bb.1: 357 successors: %bb.2 358 %unmerge_1:_(s32), %unmerge_2:_(s32) = G_UNMERGE_VALUES %unmerge_src(s64) 359 G_BR %bb.2 360 bb.2: 361 %phi:_(s32) = G_PHI %gpr_copy(s32), %bb.0, %unmerge_1(s32), %bb.1 362 $s0 = COPY %phi(s32) 363 RET_ReallyLR implicit $s0 364