1572 lines
57 KiB
YAML
1572 lines
57 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -debugify-and-strip-all-safe -mtriple aarch64 -O0 -run-pass=aarch64-prelegalizer-combiner --aarch64prelegalizercombinerhelper-only-enable-rule="load_or_combine" -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=LITTLE
|
|
# RUN: llc -debugify-and-strip-all-safe -mtriple arm64eb -O0 -run-pass=aarch64-prelegalizer-combiner --aarch64prelegalizercombinerhelper-only-enable-rule="load_or_combine" -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=BIG
|
|
|
|
# REQUIRES: asserts
|
|
|
|
# Test that we can combine patterns like
|
|
#
|
|
# s8* x = ...
|
|
# s32 y = (x[0] | (x[1] << 8)) | ((x[2] << 16) | (x[3] << 24))
|
|
#
|
|
# Into either a load, or a load with a bswap.
|
|
|
|
...
|
|
---
|
|
name: s8_loads_to_s32_little_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[0] | (x[1] << 8)) | ((x[2] << 16) | (x[3] << 24))
|
|
;
|
|
; -> Little endian: Load from x[0]
|
|
; -> Big endian: Load from x[0] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: s8_loads_to_s32_little_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: s8_loads_to_s32_little_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
%byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
|
|
; Note the shape of the tree:
|
|
;
|
|
; byte byte byte byte
|
|
; \ / \ /
|
|
; OR OR
|
|
; \ /
|
|
; \ /
|
|
; OR
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: s8_loads_to_s32_big_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[0] << 24 | (x[1] << 16)) | ((x[2] << 8) | x[3]))
|
|
;
|
|
; -> Little endian: Load from x[0] + BSWAP
|
|
; -> Big endian: Load from x[0]
|
|
|
|
; LITTLE-LABEL: name: s8_loads_to_s32_big_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; LITTLE: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: s8_loads_to_s32_big_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
|
|
%elt0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
|
|
%byte0:_(s32) = nuw G_SHL %elt0, %cst_24(s32)
|
|
%byte1:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_8(s32)
|
|
%byte3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: different_or_pattern
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; Slightly different OR tree.
|
|
;
|
|
; s8* x = ...
|
|
; s32 y = (((x[0] | (x[1] << 8)) | (x[2] << 16)) | (x[3] << 24))
|
|
;
|
|
; -> Little endian: Load from x[0]
|
|
; -> Big endian: Load from x[0] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: different_or_pattern
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: different_or_pattern
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 1)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
%byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
|
|
; Note the shape of the tree:
|
|
;
|
|
; byte byte
|
|
; \ /
|
|
; OR_1 byte
|
|
; \ /
|
|
; OR_2
|
|
; \
|
|
; ...
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %or1, %byte2
|
|
%full_load:_(s32) = G_OR %or2, %byte3
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: s16_loads_to_s32_little_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s16* x = ...
|
|
; s32 y = x[0] | (x[1] << 16)
|
|
;
|
|
; -> Little endian: Load from x[0]
|
|
; -> Big endian: Load from x[0] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: s16_loads_to_s32_little_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: s16_loads_to_s32_little_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: s16_loads_to_s32_big_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s16 *x = ...
|
|
; s32 y = x[1] | (x[0] << 16)
|
|
;
|
|
; -> Little endian: Load from x[0] + BSWAP
|
|
; -> Big endian: Load from x[0]
|
|
|
|
; LITTLE-LABEL: name: s16_loads_to_s32_big_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; LITTLE: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: s16_loads_to_s32_big_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%elt0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt0, %cst_16(s32)
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: s16_loads_to_s64_little_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s16 *x = ...
|
|
; s32 y = (x[0] | (x[1] << 16)) | ((x[2] << 32) | (x[3] << 48))
|
|
;
|
|
; -> Little endian: Load from x[0]
|
|
; -> Big endian: Load from x[0] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: s16_loads_to_s64_little_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %full_load:_(s64) = G_LOAD %ptr(p0) :: (load 8, align 2)
|
|
; LITTLE: $x1 = COPY %full_load(s64)
|
|
; LITTLE: RET_ReallyLR implicit $x1
|
|
; BIG-LABEL: name: s16_loads_to_s64_little_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD %ptr(p0) :: (load 8, align 2)
|
|
; BIG: %full_load:_(s64) = G_BSWAP [[LOAD]]
|
|
; BIG: $x1 = COPY %full_load(s64)
|
|
; BIG: RET_ReallyLR implicit $x1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_2:_(s64) = G_CONSTANT i64 2
|
|
%cst_3:_(s64) = G_CONSTANT i64 3
|
|
|
|
%cst_16:_(s64) = G_CONSTANT i64 16
|
|
%cst_32:_(s64) = G_CONSTANT i64 32
|
|
%cst_48:_(s64) = G_CONSTANT i64 48
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s64)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s64)
|
|
|
|
%byte0_byte1:_(s64) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
|
|
%elt1:_(s64) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%elt2:_(s64) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 2)
|
|
%elt3:_(s64) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 2)
|
|
|
|
%byte2_byte3:_(s64) = nuw G_SHL %elt1, %cst_16(s64)
|
|
%byte4_byte5:_(s64) = nuw G_SHL %elt2, %cst_32(s64)
|
|
%byte6_byte7:_(s64) = nuw G_SHL %elt3, %cst_48(s64)
|
|
|
|
%or1:_(s64) = G_OR %byte0_byte1, %byte2_byte3
|
|
%or2:_(s64) = G_OR %byte4_byte5, %byte6_byte7
|
|
%full_load:_(s64) = G_OR %or1, %or2
|
|
|
|
$x1 = COPY %full_load(s64)
|
|
RET_ReallyLR implicit $x1
|
|
|
|
...
|
|
---
|
|
name: s16_loads_to_s64_big_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s16 *x = ...
|
|
; s64 y = (x[3] | (x[2] << 16)) | ((x[1] << 32) | (x[0] << 48))
|
|
;
|
|
; -> Little endian: Load from x[0] + BSWAP
|
|
; -> Big endian: Load from x[0]
|
|
|
|
; LITTLE-LABEL: name: s16_loads_to_s64_big_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD %ptr(p0) :: (load 8, align 2)
|
|
; LITTLE: %full_load:_(s64) = G_BSWAP [[LOAD]]
|
|
; LITTLE: $x1 = COPY %full_load(s64)
|
|
; LITTLE: RET_ReallyLR implicit $x1
|
|
; BIG-LABEL: name: s16_loads_to_s64_big_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %full_load:_(s64) = G_LOAD %ptr(p0) :: (load 8, align 2)
|
|
; BIG: $x1 = COPY %full_load(s64)
|
|
; BIG: RET_ReallyLR implicit $x1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_2:_(s64) = G_CONSTANT i64 2
|
|
%cst_3:_(s64) = G_CONSTANT i64 3
|
|
|
|
%cst_16:_(s64) = G_CONSTANT i64 16
|
|
%cst_32:_(s64) = G_CONSTANT i64 32
|
|
%cst_48:_(s64) = G_CONSTANT i64 48
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s64)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s64)
|
|
|
|
%elt0:_(s64) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s64) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%elt2:_(s64) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 2)
|
|
|
|
%byte0_byte1:_(s64) = nuw G_SHL %elt0, %cst_48(s64)
|
|
%byte2_byte3:_(s64) = nuw G_SHL %elt1, %cst_32(s64)
|
|
%byte4_byte5:_(s64) = nuw G_SHL %elt2, %cst_16(s64)
|
|
%byte6_byte7:_(s64) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 2)
|
|
|
|
%or1:_(s64) = G_OR %byte0_byte1, %byte2_byte3
|
|
%or2:_(s64) = G_OR %byte4_byte5, %byte6_byte7
|
|
%full_load:_(s64) = G_OR %or1, %or2
|
|
|
|
$x1 = COPY %full_load(s64)
|
|
RET_ReallyLR implicit $x1
|
|
|
|
|
|
...
|
|
---
|
|
name: nonzero_start_idx_positive_little_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[1] | (x[2] << 8)) | ((x[3] << 16) | (x[4] << 24))
|
|
;
|
|
; -> Little endian: Load from x[1]
|
|
; -> Big endian: Load from x[1] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: nonzero_start_idx_positive_little_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; LITTLE: %ptr:_(p0) = COPY $x0
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr_elt_1(p0) :: (load 4, align 1)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: nonzero_start_idx_positive_little_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; BIG: %ptr:_(p0) = COPY $x0
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr_elt_1(p0) :: (load 4, align 1)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
%cst_4:_(s32) = G_CONSTANT i32 4
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x0
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
%ptr_elt_4:_(p0) = G_PTR_ADD %ptr, %cst_4(s32)
|
|
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
%elt4:_(s32) = G_ZEXTLOAD %ptr_elt_4(p0) :: (load 1)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%byte1:_(s32) = nuw G_SHL %elt2, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt3, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt4, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: nonzero_start_idx_positive_big_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[4] | (x[3] << 8)) | ((x[2] << 16) | (x[1] << 24))
|
|
;
|
|
; -> Little endian: Load from x[1] + BSWAP
|
|
; -> Big endian: Load from x[1]
|
|
|
|
; LITTLE-LABEL: name: nonzero_start_idx_positive_big_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; LITTLE: %ptr:_(p0) = COPY $x0
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; LITTLE: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr_elt_1(p0) :: (load 4, align 1)
|
|
; LITTLE: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: nonzero_start_idx_positive_big_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; BIG: %ptr:_(p0) = COPY $x0
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; BIG: %full_load:_(s32) = G_LOAD %ptr_elt_1(p0) :: (load 4, align 1)
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
%cst_4:_(s32) = G_CONSTANT i32 4
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x0
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
%ptr_elt_4:_(p0) = G_PTR_ADD %ptr, %cst_4(s32)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr_elt_4(p0) :: (load 1)
|
|
%byte1:_(s32) = nuw G_SHL %elt3, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt1, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: nonzero_start_idx_negative_little_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[-3] | (x[-2] << 8)) | ((x[-1] << 16) | (x[0] << 24))
|
|
;
|
|
; -> Little endian: Load from x[-3]
|
|
; -> Big endian: Load from x[-3] + BSWAP
|
|
|
|
; LITTLE-LABEL: name: nonzero_start_idx_negative_little_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
; LITTLE: %ptr:_(p0) = COPY $x0
|
|
; LITTLE: %ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr_elt_neg_3(p0) :: (load 4, align 1)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: nonzero_start_idx_negative_little_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
; BIG: %ptr:_(p0) = COPY $x0
|
|
; BIG: %ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr_elt_neg_3(p0) :: (load 4, align 1)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_neg_1:_(s32) = G_CONSTANT i32 -1
|
|
%cst_neg_2:_(s32) = G_CONSTANT i32 -2
|
|
%cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x0
|
|
%ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
%ptr_elt_neg_2:_(p0) = G_PTR_ADD %ptr, %cst_neg_2(s32)
|
|
%ptr_elt_neg_1:_(p0) = G_PTR_ADD %ptr, %cst_neg_1(s32)
|
|
|
|
%elt_neg_2:_(s32) = G_ZEXTLOAD %ptr_elt_neg_2(p0) :: (load 1)
|
|
%elt_neg_1:_(s32) = G_ZEXTLOAD %ptr_elt_neg_1(p0) :: (load 1)
|
|
%elt_0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr_elt_neg_3(p0) :: (load 1)
|
|
%byte1:_(s32) = nuw G_SHL %elt_neg_2, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt_neg_1, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt_0, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: nonzero_start_idx_negative_big_endian_pat
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; s8* x = ...
|
|
; s32 y = (x[0] | (x[-1] << 8)) | ((x[-2] << 16) | (x[-3] << 24))
|
|
;
|
|
; -> Little endian: Load from x[-3] + BSWAP
|
|
; -> Big endian: Load from x[-3]
|
|
|
|
; LITTLE-LABEL: name: nonzero_start_idx_negative_big_endian_pat
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
; LITTLE: %ptr:_(p0) = COPY $x0
|
|
; LITTLE: %ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
; LITTLE: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr_elt_neg_3(p0) :: (load 4, align 1)
|
|
; LITTLE: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: nonzero_start_idx_negative_big_endian_pat
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
; BIG: %ptr:_(p0) = COPY $x0
|
|
; BIG: %ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
; BIG: %full_load:_(s32) = G_LOAD %ptr_elt_neg_3(p0) :: (load 4, align 1)
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_neg_1:_(s32) = G_CONSTANT i32 -1
|
|
%cst_neg_2:_(s32) = G_CONSTANT i32 -2
|
|
%cst_neg_3:_(s32) = G_CONSTANT i32 -3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x0
|
|
%ptr_elt_neg_3:_(p0) = G_PTR_ADD %ptr, %cst_neg_3(s32)
|
|
%ptr_elt_neg_2:_(p0) = G_PTR_ADD %ptr, %cst_neg_2(s32)
|
|
%ptr_elt_neg_1:_(p0) = G_PTR_ADD %ptr, %cst_neg_1(s32)
|
|
|
|
%elt_neg_3:_(s32) = G_ZEXTLOAD %ptr_elt_neg_3(p0) :: (load 1)
|
|
%elt_neg_2:_(s32) = G_ZEXTLOAD %ptr_elt_neg_2(p0) :: (load 1)
|
|
%elt_neg_1:_(s32) = G_ZEXTLOAD %ptr_elt_neg_1(p0) :: (load 1)
|
|
%elt_0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
%byte1:_(s32) = nuw G_SHL %elt_neg_1, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt_neg_2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt_neg_3, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_volatile
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; Combine should only happen with unordered loads.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_volatile
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (volatile load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_volatile
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (volatile load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (volatile load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_wrong_memop_size
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; Combine should only happen when the loads load the same size.
|
|
|
|
; LITTLE-LABEL: name: dont_wrong_memop_size
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %wrong_size_load:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %wrong_size_load, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_wrong_memop_size
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %wrong_size_load:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %wrong_size_load, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%wrong_size_load:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%high_half:_(s32) = nuw G_SHL %wrong_size_load, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_wrong_offset
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; This is not equivalent to a 32-bit load with/without a BSWAP:
|
|
;
|
|
; s16 *x = ...
|
|
; s32 y = x[0] | (x[1] << 24)
|
|
|
|
; LITTLE-LABEL: name: dont_combine_wrong_offset
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_24(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_wrong_offset
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_24(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_24(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_wrong_offset_2
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; This does not correspond to a 32-bit load with/without a BSWAP:
|
|
;
|
|
; s16 *x = ...
|
|
; s32 y = x[0] | (x[1] << 8)
|
|
|
|
; LITTLE-LABEL: name: dont_combine_wrong_offset_2
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_wrong_offset_2
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_missing_load
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; This is missing x[2], so we shouldn't combine:
|
|
;
|
|
; s16 *x = ...
|
|
; s64 y = (x[0] | (x[1] << 16)) | (x[3] << 48)
|
|
|
|
; LITTLE-LABEL: name: dont_combine_missing_load
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_3:_(s64) = G_CONSTANT i64 3
|
|
; LITTLE: %cst_16:_(s64) = G_CONSTANT i64 16
|
|
; LITTLE: %cst_48:_(s64) = G_CONSTANT i64 48
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s64)
|
|
; LITTLE: %byte0_byte1:_(s64) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s64) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %elt3:_(s64) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 2)
|
|
; LITTLE: %byte2_byte3:_(s64) = nuw G_SHL %elt1, %cst_16(s64)
|
|
; LITTLE: %byte6_byte7:_(s64) = nuw G_SHL %elt3, %cst_48(s64)
|
|
; LITTLE: %or1:_(s64) = G_OR %byte0_byte1, %byte2_byte3
|
|
; LITTLE: %full_load:_(s64) = G_OR %or1, %byte6_byte7
|
|
; LITTLE: $x1 = COPY %full_load(s64)
|
|
; LITTLE: RET_ReallyLR implicit $x1
|
|
; BIG-LABEL: name: dont_combine_missing_load
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_3:_(s64) = G_CONSTANT i64 3
|
|
; BIG: %cst_16:_(s64) = G_CONSTANT i64 16
|
|
; BIG: %cst_48:_(s64) = G_CONSTANT i64 48
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s64)
|
|
; BIG: %byte0_byte1:_(s64) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s64) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %elt3:_(s64) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 2)
|
|
; BIG: %byte2_byte3:_(s64) = nuw G_SHL %elt1, %cst_16(s64)
|
|
; BIG: %byte6_byte7:_(s64) = nuw G_SHL %elt3, %cst_48(s64)
|
|
; BIG: %or1:_(s64) = G_OR %byte0_byte1, %byte2_byte3
|
|
; BIG: %full_load:_(s64) = G_OR %or1, %byte6_byte7
|
|
; BIG: $x1 = COPY %full_load(s64)
|
|
; BIG: RET_ReallyLR implicit $x1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_3:_(s64) = G_CONSTANT i64 3
|
|
|
|
%cst_16:_(s64) = G_CONSTANT i64 16
|
|
%cst_48:_(s64) = G_CONSTANT i64 48
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s64)
|
|
|
|
%byte0_byte1:_(s64) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
|
|
%elt1:_(s64) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%elt3:_(s64) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 2)
|
|
|
|
%byte2_byte3:_(s64) = nuw G_SHL %elt1, %cst_16(s64)
|
|
%byte6_byte7:_(s64) = nuw G_SHL %elt3, %cst_48(s64)
|
|
|
|
%or1:_(s64) = G_OR %byte0_byte1, %byte2_byte3
|
|
%full_load:_(s64) = G_OR %or1, %byte6_byte7
|
|
|
|
$x1 = COPY %full_load(s64)
|
|
RET_ReallyLR implicit $x1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_different_addr_spaces
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; When the loads are from different address spaces, don't combine.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_different_addr_spaces
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2, addrspace 1)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_different_addr_spaces
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2, addrspace 1)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2, addrspace 0)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2, addrspace 1)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_duplicate_idx
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; If two of the G_PTR_ADDs have the same index, then don't combine.
|
|
;
|
|
; sN *x = ...
|
|
; sM y = (x[i] << A) | (x[i] << B) ...
|
|
|
|
; LITTLE-LABEL: name: dont_combine_duplicate_idx
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; LITTLE: %reused_idx:_(s32) = G_CONSTANT i32 2
|
|
; LITTLE: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; LITTLE: %uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
; LITTLE: %also_uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
; LITTLE: %byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; LITTLE: %elt2:_(s32) = G_ZEXTLOAD %uses_idx_2(p0) :: (load 1)
|
|
; LITTLE: %elt3:_(s32) = G_ZEXTLOAD %also_uses_idx_2(p0) :: (load 1)
|
|
; LITTLE: %byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; LITTLE: %byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
; LITTLE: %byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
; LITTLE: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; LITTLE: %or2:_(s32) = G_OR %byte2, %byte3
|
|
; LITTLE: %full_load:_(s32) = G_OR %or1, %or2
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_duplicate_idx
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; BIG: %reused_idx:_(s32) = G_CONSTANT i32 2
|
|
; BIG: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; BIG: %uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
; BIG: %also_uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
; BIG: %byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; BIG: %elt2:_(s32) = G_ZEXTLOAD %uses_idx_2(p0) :: (load 1)
|
|
; BIG: %elt3:_(s32) = G_ZEXTLOAD %also_uses_idx_2(p0) :: (load 1)
|
|
; BIG: %byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; BIG: %byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
; BIG: %byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
; BIG: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; BIG: %or2:_(s32) = G_OR %byte2, %byte3
|
|
; BIG: %full_load:_(s32) = G_OR %or1, %or2
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%reused_idx:_(s32) = G_CONSTANT i32 2
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
%also_uses_idx_2:_(p0) = G_PTR_ADD %ptr, %reused_idx(s32)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %uses_idx_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %also_uses_idx_2(p0) :: (load 1)
|
|
|
|
%byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
...
|
|
---
|
|
name: dont_combine_duplicate_offset
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; If two of the G_SHLs have the same constant, then we should not combine.
|
|
;
|
|
; sN *x = ...
|
|
; sM y = (x[i] << A) | (x[i+1] << A) ...
|
|
|
|
; LITTLE-LABEL: name: dont_combine_duplicate_offset
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; LITTLE: %cst_2:_(s32) = G_CONSTANT i32 2
|
|
; LITTLE: %cst_3:_(s32) = G_CONSTANT i32 3
|
|
; LITTLE: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; LITTLE: %duplicate_shl_cst:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; LITTLE: %ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
; LITTLE: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
; LITTLE: %byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; LITTLE: %elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
; LITTLE: %elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
; LITTLE: %byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; LITTLE: %duplicate_shl_1:_(s32) = nuw G_SHL %elt2, %duplicate_shl_cst(s32)
|
|
; LITTLE: %duplicate_shl_2:_(s32) = nuw G_SHL %elt3, %duplicate_shl_cst(s32)
|
|
; LITTLE: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; LITTLE: %or2:_(s32) = G_OR %duplicate_shl_1, %duplicate_shl_2
|
|
; LITTLE: %full_load:_(s32) = G_OR %or1, %or2
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_duplicate_offset
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; BIG: %cst_2:_(s32) = G_CONSTANT i32 2
|
|
; BIG: %cst_3:_(s32) = G_CONSTANT i32 3
|
|
; BIG: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; BIG: %duplicate_shl_cst:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; BIG: %ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
; BIG: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
; BIG: %byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; BIG: %elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
; BIG: %elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
; BIG: %byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
; BIG: %duplicate_shl_1:_(s32) = nuw G_SHL %elt2, %duplicate_shl_cst(s32)
|
|
; BIG: %duplicate_shl_2:_(s32) = nuw G_SHL %elt3, %duplicate_shl_cst(s32)
|
|
; BIG: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; BIG: %or2:_(s32) = G_OR %duplicate_shl_1, %duplicate_shl_2
|
|
; BIG: %full_load:_(s32) = G_OR %or1, %or2
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%duplicate_shl_cst:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
%byte1:_(s32) = nuw G_SHL %elt1, %cst_8(s32)
|
|
%duplicate_shl_1:_(s32) = nuw G_SHL %elt2, %duplicate_shl_cst(s32)
|
|
%duplicate_shl_2:_(s32) = nuw G_SHL %elt3, %duplicate_shl_cst(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %duplicate_shl_1, %duplicate_shl_2
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_lowest_index_not_zero_offset
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; In this case, the lowest index load (e.g. x[0]) does not end up at byte
|
|
; offset 0. We shouldn't combine.
|
|
;
|
|
; s8 *x = ...
|
|
; s32 y = (x[0] << 8) | (x[1]) | (x[2] << 16) ...
|
|
|
|
; LITTLE-LABEL: name: dont_combine_lowest_index_not_zero_offset
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; LITTLE: %cst_2:_(s32) = G_CONSTANT i32 2
|
|
; LITTLE: %cst_3:_(s32) = G_CONSTANT i32 3
|
|
; LITTLE: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; LITTLE: %ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
; LITTLE: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
; LITTLE: %lowest_idx_load:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; LITTLE: %byte0:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; LITTLE: %elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
; LITTLE: %elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
; LITTLE: %byte1:_(s32) = nuw G_SHL %lowest_idx_load, %cst_8(s32)
|
|
; LITTLE: %byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
; LITTLE: %byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
; LITTLE: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; LITTLE: %or2:_(s32) = G_OR %byte2, %byte3
|
|
; LITTLE: %full_load:_(s32) = G_OR %or1, %or2
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_lowest_index_not_zero_offset
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s32) = G_CONSTANT i32 1
|
|
; BIG: %cst_2:_(s32) = G_CONSTANT i32 2
|
|
; BIG: %cst_3:_(s32) = G_CONSTANT i32 3
|
|
; BIG: %cst_8:_(s32) = G_CONSTANT i32 8
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %cst_24:_(s32) = G_CONSTANT i32 24
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
; BIG: %ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
; BIG: %ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
; BIG: %lowest_idx_load:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
; BIG: %byte0:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
; BIG: %elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
; BIG: %elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
; BIG: %byte1:_(s32) = nuw G_SHL %lowest_idx_load, %cst_8(s32)
|
|
; BIG: %byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
; BIG: %byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
; BIG: %or1:_(s32) = G_OR %byte0, %byte1
|
|
; BIG: %or2:_(s32) = G_OR %byte2, %byte3
|
|
; BIG: %full_load:_(s32) = G_OR %or1, %or2
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s32) = G_CONSTANT i32 1
|
|
%cst_2:_(s32) = G_CONSTANT i32 2
|
|
%cst_3:_(s32) = G_CONSTANT i32 3
|
|
|
|
%cst_8:_(s32) = G_CONSTANT i32 8
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
%cst_24:_(s32) = G_CONSTANT i32 24
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s32)
|
|
%ptr_elt_2:_(p0) = G_PTR_ADD %ptr, %cst_2(s32)
|
|
%ptr_elt_3:_(p0) = G_PTR_ADD %ptr, %cst_3(s32)
|
|
|
|
; This load is index 0
|
|
%lowest_idx_load:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 1)
|
|
%byte0:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 1)
|
|
%elt2:_(s32) = G_ZEXTLOAD %ptr_elt_2(p0) :: (load 1)
|
|
%elt3:_(s32) = G_ZEXTLOAD %ptr_elt_3(p0) :: (load 1)
|
|
|
|
; ... But it ends up being shifted, so we shouldn't combine.
|
|
%byte1:_(s32) = nuw G_SHL %lowest_idx_load, %cst_8(s32)
|
|
%byte2:_(s32) = nuw G_SHL %elt2, %cst_16(s32)
|
|
%byte3:_(s32) = nuw G_SHL %elt3, %cst_24(s32)
|
|
|
|
%or1:_(s32) = G_OR %byte0, %byte1
|
|
%or2:_(s32) = G_OR %byte2, %byte3
|
|
%full_load:_(s32) = G_OR %or1, %or2
|
|
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_more_than_one_use_load
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; If any load is used more than once, don't combine. We want to remove the
|
|
; entire tree.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_more_than_one_use_load
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: %extra_use:_(s32) = G_AND %full_load, %low_half
|
|
; LITTLE: $w1 = COPY %extra_use(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_more_than_one_use_load
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: %extra_use:_(s32) = G_AND %full_load, %low_half
|
|
; BIG: $w1 = COPY %extra_use(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
%extra_use:_(s32) = G_AND %full_load, %low_half
|
|
$w1 = COPY %extra_use(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_more_than_one_use_shl
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
|
|
; If anything feeding into any of the ors is used more than once, don't
|
|
; combine.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_more_than_one_use_shl
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: %extra_use:_(s32) = G_AND %full_load, %high_half
|
|
; LITTLE: $w1 = COPY %extra_use(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_more_than_one_use_shl
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: %extra_use:_(s32) = G_AND %full_load, %high_half
|
|
; BIG: $w1 = COPY %extra_use(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
%extra_use:_(s32) = G_AND %full_load, %high_half
|
|
$w1 = COPY %extra_use(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_store_between_same_mbb
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
; If there is a store between any of the loads, then do not combine.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_store_between_same_mbb
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: %other_ptr:_(p0) = COPY $x1
|
|
; LITTLE: %some_val:_(s32) = G_CONSTANT i32 12
|
|
; LITTLE: G_STORE %some_val(s32), %other_ptr(p0) :: (store 2)
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_store_between_same_mbb
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: %other_ptr:_(p0) = COPY $x1
|
|
; BIG: %some_val:_(s32) = G_CONSTANT i32 12
|
|
; BIG: G_STORE %some_val(s32), %other_ptr(p0) :: (store 2)
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
|
|
; Memory could be modified here, so don't combine!
|
|
%other_ptr:_(p0) = COPY $x1
|
|
%some_val:_(s32) = G_CONSTANT i32 12
|
|
G_STORE %some_val, %other_ptr :: (store 2)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: dont_combine_store_between_different_mbb
|
|
tracksRegLiveness: true
|
|
body: |
|
|
; There is a store between the two loads, hidden away in a different MBB.
|
|
; We should not combine here.
|
|
|
|
; LITTLE-LABEL: name: dont_combine_store_between_different_mbb
|
|
; LITTLE: bb.0:
|
|
; LITTLE: successors: %bb.1(0x80000000)
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: bb.1:
|
|
; LITTLE: successors: %bb.2(0x80000000)
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %other_ptr:_(p0) = COPY $x1
|
|
; LITTLE: %some_val:_(s32) = G_CONSTANT i32 12
|
|
; LITTLE: G_STORE %some_val(s32), %other_ptr(p0) :: (store 2)
|
|
; LITTLE: bb.2:
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: dont_combine_store_between_different_mbb
|
|
; BIG: bb.0:
|
|
; BIG: successors: %bb.1(0x80000000)
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: bb.1:
|
|
; BIG: successors: %bb.2(0x80000000)
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %other_ptr:_(p0) = COPY $x1
|
|
; BIG: %some_val:_(s32) = G_CONSTANT i32 12
|
|
; BIG: G_STORE %some_val(s32), %other_ptr(p0) :: (store 2)
|
|
; BIG: bb.2:
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
|
|
bb.0:
|
|
successors: %bb.1(0x80000000)
|
|
liveins: $x0, $x1
|
|
; If there is a store between any of the loads, then do not combine.
|
|
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
|
|
bb.1:
|
|
liveins: $x0, $x1
|
|
successors: %bb.2(0x80000000)
|
|
; Memory could be modified here, so don't combine!
|
|
%other_ptr:_(p0) = COPY $x1
|
|
%some_val:_(s32) = G_CONSTANT i32 12
|
|
G_STORE %some_val, %other_ptr :: (store 2)
|
|
|
|
bb.2:
|
|
liveins: $x0, $x1
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: different_mbb
|
|
tracksRegLiveness: true
|
|
body: |
|
|
; It should be possible to combine here, but it's not supported right now.
|
|
|
|
; LITTLE-LABEL: name: different_mbb
|
|
; LITTLE: bb.0:
|
|
; LITTLE: successors: %bb.1(0x80000000)
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; LITTLE: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; LITTLE: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; LITTLE: bb.1:
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; LITTLE: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; LITTLE: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: different_mbb
|
|
; BIG: bb.0:
|
|
; BIG: successors: %bb.1(0x80000000)
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %cst_1:_(s64) = G_CONSTANT i64 1
|
|
; BIG: %cst_16:_(s32) = G_CONSTANT i32 16
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: %ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
; BIG: %low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
; BIG: bb.1:
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
; BIG: %high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
; BIG: %full_load:_(s32) = G_OR %low_half, %high_half
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
|
|
bb.0:
|
|
successors: %bb.1(0x80000000)
|
|
liveins: $x0, $x1
|
|
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
|
|
bb.1:
|
|
liveins: $x0, $x1
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|
|
|
|
...
|
|
---
|
|
name: load_first
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $x0, $x1
|
|
; Test for a bug fix for predecessor-checking code.
|
|
|
|
; LITTLE-LABEL: name: load_first
|
|
; LITTLE: liveins: $x0, $x1
|
|
; LITTLE: %ptr:_(p0) = COPY $x1
|
|
; LITTLE: %full_load:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; LITTLE: $w1 = COPY %full_load(s32)
|
|
; LITTLE: RET_ReallyLR implicit $w1
|
|
; BIG-LABEL: name: load_first
|
|
; BIG: liveins: $x0, $x1
|
|
; BIG: %ptr:_(p0) = COPY $x1
|
|
; BIG: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD %ptr(p0) :: (load 4, align 2)
|
|
; BIG: %full_load:_(s32) = G_BSWAP [[LOAD]]
|
|
; BIG: $w1 = COPY %full_load(s32)
|
|
; BIG: RET_ReallyLR implicit $w1
|
|
%low_half:_(s32) = G_ZEXTLOAD %ptr(p0) :: (load 2)
|
|
%cst_1:_(s64) = G_CONSTANT i64 1
|
|
%cst_16:_(s32) = G_CONSTANT i32 16
|
|
|
|
%ptr:_(p0) = COPY $x1
|
|
%ptr_elt_1:_(p0) = G_PTR_ADD %ptr, %cst_1(s64)
|
|
|
|
%elt1:_(s32) = G_ZEXTLOAD %ptr_elt_1(p0) :: (load 2)
|
|
%high_half:_(s32) = nuw G_SHL %elt1, %cst_16(s32)
|
|
|
|
%full_load:_(s32) = G_OR %low_half, %high_half
|
|
$w1 = COPY %full_load(s32)
|
|
RET_ReallyLR implicit $w1
|