| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| # RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s |
| ... |
| --- |
| name: shl_gep_sext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0 |
| |
| ; We should be able to fold a shift + extend into the pattern. |
| ; In this case, we should get a roW load with two 1s, representing a shift |
| ; plus sign extend. |
| |
| ; CHECK-LABEL: name: shl_gep_sext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 1, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_SEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 2 |
| %offset:gpr(s64) = G_SHL %ext, %c |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: shl_gep_zext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0 |
| |
| ; We should be able to fold a shift + extend into the pattern. |
| ; In this case, we should get a roW load with a 0 representing a zero-extend |
| ; and a 1 representing a shift. |
| |
| ; CHECK-LABEL: name: shl_gep_zext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_ZEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 2 |
| %offset:gpr(s64) = G_SHL %ext, %c |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: shl_gep_anyext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0 |
| |
| ; We should be able to fold a shift + extend into the pattern. |
| ; In this case, we should get a roW load with a 0 representing a zero-extend |
| ; and a 1 representing a shift. |
| |
| ; CHECK-LABEL: name: shl_gep_anyext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_ANYEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 2 |
| %offset:gpr(s64) = G_SHL %ext, %c |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: mul_gep_sext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| |
| ; We should be able to do the same with multiplies as with shifts. |
| |
| liveins: $w1, $x0 |
| ; CHECK-LABEL: name: mul_gep_sext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 1, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_SEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 4 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: mul_gep_zext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0 |
| |
| ; We should be able to do the same with multiplies as with shifts. |
| |
| ; CHECK-LABEL: name: mul_gep_zext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_ZEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 4 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: mul_gep_anyext_ldrwrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0 |
| |
| ; We should be able to do the same with multiplies as with shifts. |
| |
| ; CHECK-LABEL: name: mul_gep_anyext_ldrwrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr32 = LDRWroW %base, %foo, 0, 1 :: (load 4) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_ANYEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 4 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 4) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: ldrdrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0, $d0 |
| |
| ; Verify that we can select LDRDroW. |
| |
| ; CHECK-LABEL: name: ldrdrow |
| ; CHECK: liveins: $w1, $x0, $d0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:fpr64 = LDRDroW %base, %foo, 1, 1 :: (load 8) |
| ; CHECK: $x0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $x0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_SEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 8 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:fpr(<2 x s32>) = G_LOAD %ptr(p0) :: (load 8) |
| $x0 = COPY %load(<2 x s32>) |
| RET_ReallyLR implicit $x0 |
| ... |
| --- |
| name: ldrxrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.0: |
| liveins: $w1, $x0, $d0 |
| |
| ; Verify that we can select LDRXroW. |
| |
| ; CHECK-LABEL: name: ldrxrow |
| ; CHECK: liveins: $w1, $x0, $d0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:gpr64 = LDRXroW %base, %foo, 1, 1 :: (load 8) |
| ; CHECK: $x0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $x0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_SEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 8 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:gpr(s64) = G_LOAD %ptr(p0) :: (load 8) |
| $x0 = COPY %load(s64) |
| RET_ReallyLR implicit $x0 |
| ... |
| --- |
| name: ldrbbrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.1.entry: |
| liveins: $x0, $w0, $w1 |
| |
| ; Verify that we can select LDRBBroW. Note that there is no shift here, |
| ; but we still fold the extend into the addressing mode. |
| |
| ; CHECK-LABEL: name: ldrbbrow |
| ; CHECK: liveins: $x0, $w0, $w1 |
| ; CHECK: %val:gpr32 = COPY $w1 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %load:gpr32 = LDRBBroW %base, %val, 1, 0 :: (load 1) |
| ; CHECK: $w0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %val:gpr(s32) = COPY $w1 |
| %base:gpr(p0) = COPY $x0 |
| %ext:gpr(s64) = G_SEXT %val(s32) |
| %ptr:gpr(p0) = G_PTR_ADD %base, %ext(s64) |
| %load:gpr(s32) = G_LOAD %ptr(p0) :: (load 1) |
| $w0 = COPY %load(s32) |
| RET_ReallyLR implicit $w0 |
| ... |
| --- |
| name: ldrhrow |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| machineFunctionInfo: {} |
| body: | |
| bb.1.entry: |
| liveins: $w1, $x0 |
| |
| ; Verify that we can select ldrhrow. |
| |
| ; CHECK-LABEL: name: ldrhrow |
| ; CHECK: liveins: $w1, $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %foo:gpr32 = COPY $w1 |
| ; CHECK: %load:fpr16 = LDRHroW %base, %foo, 1, 1 :: (load 2) |
| ; CHECK: $h0 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $h0 |
| %base:gpr(p0) = COPY $x0 |
| %foo:gpr(s32) = COPY $w1 |
| %ext:gpr(s64) = G_SEXT %foo(s32) |
| %c:gpr(s64) = G_CONSTANT i64 2 |
| %offset:gpr(s64) = G_MUL %c, %ext |
| %ptr:gpr(p0) = G_PTR_ADD %base, %offset(s64) |
| %load:fpr(s16) = G_LOAD %ptr(p0) :: (load 2) |
| $h0 = COPY %load(s16) |
| RET_ReallyLR implicit $h0 |
| ... |
| --- |
| name: bad_and_mask_1 |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| body: | |
| bb.0: |
| liveins: $x0 |
| |
| ; We should get a roX load here, not a roW load. We can't use the mask in |
| ; this test for an extend. |
| |
| ; CHECK-LABEL: name: bad_and_mask_1 |
| ; CHECK: liveins: $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %imp:gpr64 = IMPLICIT_DEF |
| ; CHECK: %and:gpr64common = ANDXri %imp, 4103 |
| ; CHECK: %load:gpr64 = LDRXroX %base, %and, 0, 1 :: (load 8) |
| ; CHECK: $x1 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $x1 |
| %base:gpr(p0) = COPY $x0 |
| %imp:gpr(s64) = G_IMPLICIT_DEF |
| %bad_mask:gpr(s64) = G_CONSTANT i64 255 |
| %and:gpr(s64) = G_AND %imp, %bad_mask |
| %c:gpr(s64) = G_CONSTANT i64 8 |
| %mul:gpr(s64) = G_MUL %c, %and |
| %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64) |
| %load:gpr(s64) = G_LOAD %ptr(p0) :: (load 8) |
| $x1 = COPY %load(s64) |
| RET_ReallyLR implicit $x1 |
| ... |
| --- |
| name: bad_and_mask_2 |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| body: | |
| bb.0: |
| liveins: $x0 |
| |
| ; We should get a roX load here, not a roW load. We can't use the mask in |
| ; this test for an extend. |
| |
| ; CHECK-LABEL: name: bad_and_mask_2 |
| ; CHECK: liveins: $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %imp:gpr64 = IMPLICIT_DEF |
| ; CHECK: %and:gpr64common = ANDXri %imp, 4111 |
| ; CHECK: %load:gpr64 = LDRXroX %base, %and, 0, 1 :: (load 8) |
| ; CHECK: $x1 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $x1 |
| %base:gpr(p0) = COPY $x0 |
| %imp:gpr(s64) = G_IMPLICIT_DEF |
| %bad_mask:gpr(s64) = G_CONSTANT i64 65535 |
| %and:gpr(s64) = G_AND %imp, %bad_mask |
| %c:gpr(s64) = G_CONSTANT i64 8 |
| %mul:gpr(s64) = G_MUL %c, %and |
| %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64) |
| %load:gpr(s64) = G_LOAD %ptr(p0) :: (load 8) |
| $x1 = COPY %load(s64) |
| RET_ReallyLR implicit $x1 |
| ... |
| --- |
| name: and_uxtw |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| frameInfo: |
| maxAlignment: 1 |
| body: | |
| bb.0: |
| liveins: $x0 |
| |
| ; The mask used for the AND here is legal for producing a roW load. |
| |
| ; CHECK-LABEL: name: and_uxtw |
| ; CHECK: liveins: $x0 |
| ; CHECK: %base:gpr64sp = COPY $x0 |
| ; CHECK: %imp:gpr64 = IMPLICIT_DEF |
| ; CHECK: [[COPY:%[0-9]+]]:gpr32all = COPY %imp.sub_32 |
| ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]] |
| ; CHECK: %load:gpr64 = LDRXroW %base, [[COPY1]], 0, 1 :: (load 8) |
| ; CHECK: $x1 = COPY %load |
| ; CHECK: RET_ReallyLR implicit $x1 |
| %base:gpr(p0) = COPY $x0 |
| %imp:gpr(s64) = G_IMPLICIT_DEF |
| %mask:gpr(s64) = G_CONSTANT i64 4294967295 |
| %and:gpr(s64) = G_AND %imp, %mask |
| %c:gpr(s64) = G_CONSTANT i64 8 |
| %mul:gpr(s64) = G_MUL %c, %and |
| %ptr:gpr(p0) = G_PTR_ADD %base, %mul(s64) |
| %load:gpr(s64) = G_LOAD %ptr(p0) :: (load 8) |
| $x1 = COPY %load(s64) |
| RET_ReallyLR implicit $x1 |
| ... |
| --- |
| name: zext_shl_LDRWroW |
| alignment: 4 |
| legalized: true |
| regBankSelected: true |
| tracksRegLiveness: true |
| liveins: |
| - { reg: '$w0' } |
| - { reg: '$x1' } |
| body: | |
| bb.1: |
| liveins: $w0, $x1 |
| |
| ; We try to look through the G_ZEXT of the SHL here. |
| |
| ; CHECK-LABEL: name: zext_shl_LDRWroW |
| ; CHECK: liveins: $w0, $x1 |
| ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 |
| ; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x1 |
| ; CHECK: [[ANDWri:%[0-9]+]]:gpr32common = ANDWri [[COPY]], 7 |
| ; CHECK: [[LDRWroW:%[0-9]+]]:gpr32 = LDRWroW [[COPY1]], [[ANDWri]], 0, 1 :: (load 4) |
| ; CHECK: $w0 = COPY [[LDRWroW]] |
| ; CHECK: RET_ReallyLR implicit $w0 |
| %0:gpr(s32) = COPY $w0 |
| %1:gpr(p0) = COPY $x1 |
| %2:gpr(s32) = G_CONSTANT i32 255 |
| %3:gpr(s32) = G_AND %0, %2 |
| %13:gpr(s64) = G_CONSTANT i64 2 |
| %12:gpr(s32) = G_SHL %3, %13(s64) |
| %6:gpr(s64) = G_ZEXT %12(s32) |
| %7:gpr(p0) = G_PTR_ADD %1, %6(s64) |
| %9:gpr(s32) = G_LOAD %7(p0) :: (load 4) |
| $w0 = COPY %9(s32) |
| RET_ReallyLR implicit $w0 |
| |
| ... |