| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| # RUN: llc -O0 -mtriple=aarch64-apple-ios -run-pass=localizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefix=CHECK |
| |
| # Test the localizer. |
| |
| --- | |
| target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" |
| |
| define void @local_use() { ret void } |
| define void @non_local_1use() { ret void } |
| define void @non_local_2uses() { ret void } |
| define void @non_local_phi_use() { ret void } |
| define void @non_local_phi_use_followed_by_use() { ret void } |
| define void @non_local_phi_use_followed_by_use_fi() { ret void } |
| define void @float_non_local_phi_use_followed_by_use_fi() { ret void } |
| define void @non_local_phi() { ret void } |
| define void @non_local_label() { ret void } |
| |
| @var1 = common global i32 0, align 4 |
| @var2 = common global i32 0, align 4 |
| @var3 = common global i32 0, align 4 |
| @var4 = common global i32 0, align 4 |
| |
| define i32 @intrablock_with_globalvalue() { |
| entry: |
| %0 = load i32, i32* @var1, align 4 |
| %cmp = icmp eq i32 %0, 1 |
| br i1 %cmp, label %if.then, label %if.end |
| |
| if.then: |
| store i32 2, i32* @var2, align 4 |
| store i32 3, i32* @var1, align 4 |
| store i32 2, i32* @var3, align 4 |
| store i32 3, i32* @var1, align 4 |
| br label %if.end |
| |
| if.end: |
| ret i32 0 |
| } |
| define i32 @adrp_add() { |
| entry: |
| %0 = load i32, i32* @var1, align 4 |
| %cmp = icmp eq i32 %0, 1 |
| br i1 %cmp, label %if.then, label %if.end |
| |
| if.then: |
| store i32 2, i32* @var2, align 4 |
| store i32 3, i32* @var1, align 4 |
| store i32 2, i32* @var3, align 4 |
| store i32 3, i32* @var1, align 4 |
| br label %if.end |
| |
| if.end: |
| ret i32 0 |
| } |
| |
| define void @test_inttoptr() { ret void } |
| define void @many_local_use_intra_block() { ret void } |
| define void @non_local_phi_use_nonunique() { ret void } |
| ... |
| |
| --- |
| name: local_use |
| legalized: true |
| regBankSelected: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: local_use |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| ... |
| |
| --- |
| name: non_local_1use |
| legalized: true |
| regBankSelected: true |
| body: | |
| ; CHECK-LABEL: name: non_local_1use |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[C1]], [[ADD]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| |
| bb.1: |
| %2:gpr(s32) = G_ADD %0, %1 |
| ... |
| |
| --- |
| name: non_local_2uses |
| legalized: true |
| regBankSelected: true |
| body: | |
| ; CHECK-LABEL: name: non_local_2uses |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[C1]], [[C1]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| |
| bb.1: |
| %2:gpr(s32) = G_ADD %0, %0 |
| ... |
| |
| --- |
| name: non_local_phi_use |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_phi_use |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: bb.2: |
| ; CHECK: [[PHI:%[0-9]+]]:gpr(s32) = PHI [[C1]](s32), %bb.1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[PHI]], [[PHI]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| |
| bb.1: |
| successors: %bb.2 |
| |
| bb.2: |
| %3:gpr(s32) = PHI %0(s32), %bb.1 |
| %2:gpr(s32) = G_ADD %3, %3 |
| ... |
| |
| --- |
| name: non_local_phi_use_followed_by_use |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_phi_use_followed_by_use |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: bb.2: |
| ; CHECK: [[PHI:%[0-9]+]]:gpr(s32) = PHI [[C1]](s32), %bb.1 |
| ; CHECK: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[PHI]], [[C2]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| |
| bb.1: |
| successors: %bb.2 |
| |
| bb.2: |
| %3:gpr(s32) = PHI %0(s32), %bb.1 |
| %2:gpr(s32) = G_ADD %3, %0 |
| ... |
| |
| --- |
| name: non_local_phi_use_followed_by_use_fi |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_phi_use_followed_by_use_fi |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[FRAME_INDEX:%[0-9]+]]:gpr(s32) = G_FRAME_INDEX 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[FRAME_INDEX]], [[FRAME_INDEX]] |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:gpr(s32) = G_FRAME_INDEX 1 |
| ; CHECK: bb.2: |
| ; CHECK: [[PHI:%[0-9]+]]:gpr(s32) = PHI [[FRAME_INDEX1]](s32), %bb.1 |
| ; CHECK: [[FRAME_INDEX2:%[0-9]+]]:gpr(s32) = G_FRAME_INDEX 1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[PHI]], [[FRAME_INDEX2]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:gpr(s32) = G_FRAME_INDEX 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| |
| bb.1: |
| successors: %bb.2 |
| |
| bb.2: |
| %3:gpr(s32) = PHI %0(s32), %bb.1 |
| %2:gpr(s32) = G_ADD %3, %0 |
| ... |
| |
| --- |
| name: float_non_local_phi_use_followed_by_use_fi |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: float_non_local_phi_use_followed_by_use_fi |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: [[FADD:%[0-9]+]]:fpr(s32) = G_FADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[C1:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: bb.2: |
| ; CHECK: [[PHI:%[0-9]+]]:fpr(s32) = PHI [[C1]](s32), %bb.1 |
| ; CHECK: [[C2:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: [[FADD1:%[0-9]+]]:fpr(s32) = G_FADD [[PHI]], [[C2]] |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:fpr(s32) = G_FCONSTANT float 1.0 |
| %1:fpr(s32) = G_FADD %0, %0 |
| |
| bb.1: |
| successors: %bb.2 |
| |
| bb.2: |
| %3:fpr(s32) = PHI %0(s32), %bb.1 |
| %2:fpr(s32) = G_FADD %3, %0 |
| ... |
| |
| --- |
| # Make sure we don't insert a constant before PHIs. |
| # This used to happen for loops of one basic block. |
| name: non_local_phi |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_phi |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[C:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: [[FADD:%[0-9]+]]:fpr(s32) = G_FADD [[C]], [[C]] |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: [[PHI:%[0-9]+]]:fpr(s32) = PHI [[FADD]](s32), %bb.0, %4(s32), %bb.1 |
| ; CHECK: [[C1:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: [[FADD1:%[0-9]+]]:fpr(s32) = G_FADD [[PHI]], [[FADD]] |
| ; CHECK: G_BR %bb.1 |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| successors: %bb.1 |
| |
| %0:fpr(s32) = G_FCONSTANT float 1.0 |
| %1:fpr(s32) = G_FADD %0, %0 |
| |
| bb.1: |
| successors: %bb.1 |
| |
| %3:fpr(s32) = PHI %1(s32), %bb.0, %0(s32), %bb.1 |
| %2:fpr(s32) = G_FADD %3, %1 |
| G_BR %bb.1 |
| ... |
| |
| --- |
| # Make sure we don't insert a constant before EH_LABELs. |
| name: non_local_label |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_label |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: liveins: $s0 |
| ; CHECK: [[COPY:%[0-9]+]]:fpr(s32) = COPY $s0 |
| ; CHECK: [[C:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.1(0x80000000) |
| ; CHECK: EH_LABEL 1 |
| ; CHECK: [[C1:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00 |
| ; CHECK: [[FADD:%[0-9]+]]:fpr(s32) = G_FADD [[COPY]], [[C1]] |
| ; CHECK: G_BR %bb.1 |
| |
| ; Existing registers should be left untouched |
| ; The newly created reg should be on the same regbank/regclass as its origin. |
| |
| bb.0: |
| liveins: $s0 |
| successors: %bb.1 |
| |
| %0:fpr(s32) = COPY $s0 |
| %1:fpr(s32) = G_FCONSTANT float 1.0 |
| |
| bb.1: |
| successors: %bb.1 |
| |
| EH_LABEL 1 |
| %2:fpr(s32) = G_FADD %0, %1 |
| G_BR %bb.1 |
| ... |
| --- |
| name: intrablock_with_globalvalue |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: intrablock_with_globalvalue |
| ; CHECK: bb.0.entry: |
| ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 2 |
| ; CHECK: [[GV:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var2 |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3 |
| ; CHECK: [[GV1:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var3 |
| ; CHECK: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0 |
| ; CHECK: [[GV2:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var1 |
| ; CHECK: [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[GV2]](p0) :: (load (s32) from @var1) |
| ; CHECK: [[C3:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ICMP:%[0-9]+]]:gpr(s32) = G_ICMP intpred(eq), [[LOAD]](s32), [[C3]] |
| ; CHECK: [[TRUNC:%[0-9]+]]:gpr(s1) = G_TRUNC [[ICMP]](s32) |
| ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.1 |
| ; CHECK: G_BR %bb.2 |
| ; CHECK: bb.1.if.then: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[GV3:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var2 |
| ; CHECK: [[C4:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 2 |
| ; CHECK: G_STORE [[C4]](s32), [[GV3]](p0) :: (store (s32) into @var2) |
| ; CHECK: [[C5:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3 |
| ; CHECK: [[GV4:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var1 |
| ; CHECK: G_STORE [[C5]](s32), [[GV4]](p0) :: (store (s32) into @var1) |
| ; CHECK: [[GV5:%[0-9]+]]:gpr(p0) = G_GLOBAL_VALUE @var3 |
| ; CHECK: G_STORE [[C4]](s32), [[GV5]](p0) :: (store (s32) into @var3) |
| ; CHECK: G_STORE [[C5]](s32), [[GV4]](p0) :: (store (s32) into @var1) |
| ; CHECK: bb.2.if.end: |
| ; CHECK: [[C6:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0 |
| ; CHECK: $w0 = COPY [[C6]](s32) |
| ; CHECK: RET_ReallyLR implicit $w0 |
| |
| ; Some of these instructions are dead. We're checking that the other instructions are |
| ; sunk immediately before their first user in the if.then block or as close as possible. |
| bb.1.entry: |
| %1:gpr(p0) = G_GLOBAL_VALUE @var1 |
| %2:gpr(s32) = G_CONSTANT i32 1 |
| %4:gpr(s32) = G_CONSTANT i32 2 |
| %5:gpr(p0) = G_GLOBAL_VALUE @var2 |
| %6:gpr(s32) = G_CONSTANT i32 3 |
| %7:gpr(p0) = G_GLOBAL_VALUE @var3 |
| %8:gpr(s32) = G_CONSTANT i32 0 |
| %0:gpr(s32) = G_LOAD %1(p0) :: (load (s32) from @var1) |
| %9:gpr(s32) = G_ICMP intpred(eq), %0(s32), %2 |
| %3:gpr(s1) = G_TRUNC %9(s32) |
| G_BRCOND %3(s1), %bb.2 |
| G_BR %bb.3 |
| |
| bb.2.if.then: |
| G_STORE %4(s32), %5(p0) :: (store (s32) into @var2) |
| G_STORE %6(s32), %1(p0) :: (store (s32) into @var1) |
| G_STORE %4(s32), %7(p0) :: (store (s32) into @var3) |
| G_STORE %6(s32), %1(p0) :: (store (s32) into @var1) |
| |
| bb.3.if.end: |
| $w0 = COPY %8(s32) |
| RET_ReallyLR implicit $w0 |
| |
| ... |
| --- |
| name: adrp_add |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: adrp_add |
| ; CHECK: bb.0.entry: |
| ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) |
| ; CHECK: [[ADRP:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var1 |
| ; CHECK: %addlow1:gpr(p0) = G_ADD_LOW [[ADRP]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var1 |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 2 |
| ; CHECK: [[ADRP1:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var2 |
| ; CHECK: %addlow2:gpr(p0) = G_ADD_LOW [[ADRP1]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var2 |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3 |
| ; CHECK: [[ADRP2:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var3 |
| ; CHECK: %addlow3:gpr(p0) = G_ADD_LOW [[ADRP2]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var3 |
| ; CHECK: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0 |
| ; CHECK: [[LOAD:%[0-9]+]]:gpr(s32) = G_LOAD [[ADRP]](p0) :: (load (s32) from @var1) |
| ; CHECK: [[C3:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ICMP:%[0-9]+]]:gpr(s32) = G_ICMP intpred(eq), [[LOAD]](s32), [[C3]] |
| ; CHECK: [[TRUNC:%[0-9]+]]:gpr(s1) = G_TRUNC [[ICMP]](s32) |
| ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.1 |
| ; CHECK: G_BR %bb.2 |
| ; CHECK: bb.1.if.then: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: [[ADRP3:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var2 |
| ; CHECK: [[ADD_LOW:%[0-9]+]]:gpr(p0) = G_ADD_LOW [[ADRP3]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var2 |
| ; CHECK: [[C4:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 2 |
| ; CHECK: G_STORE [[C4]](s32), [[ADD_LOW]](p0) :: (store (s32) into @var2) |
| ; CHECK: [[C5:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3 |
| ; CHECK: [[ADRP4:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var1 |
| ; CHECK: [[ADD_LOW1:%[0-9]+]]:gpr(p0) = G_ADD_LOW [[ADRP4]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var1 |
| ; CHECK: G_STORE [[C5]](s32), [[ADD_LOW1]](p0) :: (store (s32) into @var1) |
| ; CHECK: [[ADRP5:%[0-9]+]]:gpr64(p0) = ADRP target-flags(aarch64-page) @var3 |
| ; CHECK: [[ADD_LOW2:%[0-9]+]]:gpr(p0) = G_ADD_LOW [[ADRP5]](p0), target-flags(aarch64-pageoff, aarch64-nc) @var3 |
| ; CHECK: G_STORE [[C4]](s32), [[ADD_LOW2]](p0) :: (store (s32) into @var3) |
| ; CHECK: G_STORE [[C5]](s32), [[ADD_LOW1]](p0) :: (store (s32) into @var1) |
| ; CHECK: bb.2.if.end: |
| ; CHECK: [[C6:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0 |
| ; CHECK: $w0 = COPY [[C6]](s32) |
| ; CHECK: RET_ReallyLR implicit $w0 |
| |
| ; Some of these instructions are dead. |
| bb.1.entry: |
| %1:gpr64(p0) = ADRP target-flags(aarch64-page) @var1 |
| %addlow1:gpr(p0) = G_ADD_LOW %1(p0), target-flags(aarch64-pageoff, aarch64-nc) @var1 |
| %2:gpr(s32) = G_CONSTANT i32 1 |
| %4:gpr(s32) = G_CONSTANT i32 2 |
| %5:gpr64(p0) = ADRP target-flags(aarch64-page) @var2 |
| %addlow2:gpr(p0) = G_ADD_LOW %5(p0), target-flags(aarch64-pageoff, aarch64-nc) @var2 |
| %6:gpr(s32) = G_CONSTANT i32 3 |
| %7:gpr64(p0) = ADRP target-flags(aarch64-page) @var3 |
| %addlow3:gpr(p0) = G_ADD_LOW %7(p0), target-flags(aarch64-pageoff, aarch64-nc) @var3 |
| %8:gpr(s32) = G_CONSTANT i32 0 |
| %0:gpr(s32) = G_LOAD %1(p0) :: (load (s32) from @var1) |
| %9:gpr(s32) = G_ICMP intpred(eq), %0(s32), %2 |
| %3:gpr(s1) = G_TRUNC %9(s32) |
| G_BRCOND %3(s1), %bb.2 |
| G_BR %bb.3 |
| |
| bb.2.if.then: |
| G_STORE %4(s32), %addlow2(p0) :: (store (s32) into @var2) |
| G_STORE %6(s32), %addlow1(p0) :: (store (s32) into @var1) |
| G_STORE %4(s32), %addlow3(p0) :: (store (s32) into @var3) |
| G_STORE %6(s32), %addlow1(p0) :: (store (s32) into @var1) |
| |
| bb.3.if.end: |
| $w0 = COPY %8(s32) |
| RET_ReallyLR implicit $w0 |
| |
| ... |
| --- |
| name: test_inttoptr |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: test_inttoptr |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) |
| ; CHECK: liveins: $w0, $x1 |
| ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0 |
| ; CHECK: [[COPY1:%[0-9]+]]:gpr(p0) = COPY $x1 |
| ; CHECK: [[C:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 0 |
| ; CHECK: [[INTTOPTR:%[0-9]+]]:gpr(p0) = G_INTTOPTR [[C]](s64) |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 128 |
| ; CHECK: [[INTTOPTR1:%[0-9]+]]:gpr(p0) = G_INTTOPTR [[C1]](s64) |
| ; CHECK: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 0 |
| ; CHECK: [[ICMP:%[0-9]+]]:gpr(s32) = G_ICMP intpred(eq), [[COPY]](s32), [[C2]] |
| ; CHECK: [[TRUNC:%[0-9]+]]:gpr(s1) = G_TRUNC [[ICMP]](s32) |
| ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.1 |
| ; CHECK: G_BR %bb.2 |
| ; CHECK: bb.1: |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[COPY]], [[COPY]] |
| ; CHECK: G_STORE [[ADD]](s32), [[COPY1]](p0) :: (store (s32) |
| ; CHECK: [[C3:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 128 |
| ; CHECK: [[INTTOPTR2:%[0-9]+]]:gpr(p0) = G_INTTOPTR [[C3]](s64) |
| ; CHECK: $x0 = COPY [[INTTOPTR2]](p0) |
| ; CHECK: RET_ReallyLR implicit $x0 |
| ; CHECK: bb.2: |
| ; CHECK: [[C4:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 0 |
| ; CHECK: [[INTTOPTR3:%[0-9]+]]:gpr(p0) = G_INTTOPTR [[C4]](s64) |
| ; CHECK: $x0 = COPY [[INTTOPTR3]](p0) |
| ; CHECK: RET_ReallyLR implicit $x0 |
| bb.1: |
| liveins: $w0, $x1 |
| |
| %0:gpr(s32) = COPY $w0 |
| %1:gpr(p0) = COPY $x1 |
| %2:gpr(s64) = G_CONSTANT i64 128 |
| %4:gpr(s32) = G_CONSTANT i32 0 |
| %7:gpr(s64) = G_CONSTANT i64 0 |
| %6:gpr(p0) = G_INTTOPTR %7(s64) |
| %3:gpr(p0) = G_INTTOPTR %2(s64) |
| %9:gpr(s32) = G_ICMP intpred(eq), %0(s32), %4 |
| %5:gpr(s1) = G_TRUNC %9(s32) |
| G_BRCOND %5(s1), %bb.2 |
| G_BR %bb.3 |
| |
| bb.2: |
| %8:gpr(s32) = G_ADD %0, %0 |
| G_STORE %8(s32), %1(p0) :: (store (s32)) |
| $x0 = COPY %3(p0) |
| RET_ReallyLR implicit $x0 |
| |
| bb.3: |
| $x0 = COPY %6(p0) |
| RET_ReallyLR implicit $x0 |
| |
| ... |
| |
| --- |
| name: many_local_use_intra_block |
| legalized: true |
| regBankSelected: true |
| body: | |
| bb.0: |
| ; CHECK-LABEL: name: many_local_use_intra_block |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: [[ADD2:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: [[ADD3:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: [[ADD4:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 2 |
| ; CHECK: [[ADD5:%[0-9]+]]:gpr(s32) = G_ADD [[C1]], [[C1]] |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_CONSTANT i32 2 |
| %2:gpr(s32) = G_ADD %0, %0 |
| %3:gpr(s32) = G_ADD %0, %0 |
| %4:gpr(s32) = G_ADD %0, %0 |
| %5:gpr(s32) = G_ADD %0, %0 |
| %6:gpr(s32) = G_ADD %0, %0 |
| %7:gpr(s32) = G_ADD %1, %1 |
| ... |
| |
| --- |
| name: non_local_phi_use_nonunique |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| body: | |
| ; CHECK-LABEL: name: non_local_phi_use_nonunique |
| ; CHECK: bb.0: |
| ; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000) |
| ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 1 |
| ; CHECK: [[ADD:%[0-9]+]]:gpr(s32) = G_ADD [[C]], [[C]] |
| ; CHECK: %cmp:gpr(s32) = G_ICMP intpred(eq), [[ADD]](s32), [[C]] |
| ; CHECK: %cond:gpr(s1) = G_TRUNC %cmp(s32) |
| ; CHECK: G_BRCOND %cond(s1), %bb.1 |
| ; CHECK: G_BR %bb.2 |
| ; CHECK: bb.1: |
| ; CHECK: successors: %bb.2(0x80000000) |
| ; CHECK: bb.2: |
| ; CHECK: [[PHI:%[0-9]+]]:gpr(s32) = G_PHI [[C]](s32), %bb.1 |
| ; CHECK: [[ADD1:%[0-9]+]]:gpr(s32) = G_ADD [[PHI]], [[PHI]] |
| |
| ; Don't localize the 1 into bb.1, because there are multiple edges |
| ; using that register. |
| |
| bb.0: |
| successors: %bb.1, %bb.2 |
| |
| %0:gpr(s32) = G_CONSTANT i32 1 |
| %1:gpr(s32) = G_ADD %0, %0 |
| %cmp:gpr(s32) = G_ICMP intpred(eq), %1(s32), %0 |
| %cond:gpr(s1) = G_TRUNC %cmp(s32) |
| G_BRCOND %cond(s1), %bb.1 |
| G_BR %bb.2 |
| |
| bb.1: |
| successors: %bb.2 |
| |
| bb.2: |
| %3:gpr(s32) = G_PHI %0(s32), %bb.1, %0(s32), %bb.0 |
| %2:gpr(s32) = G_ADD %3, %3 |
| ... |