mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
9d1f0bd735
This opportunity is found from spec 2017 557.xz_r. And it is used by the sha encrypt/decrypt. See sha-2/sha512.c static void store64(u64 x, unsigned char* y) { for(int i = 0; i != 8; ++i) y[i] = (x >> ((7-i) * 8)) & 255; } static u64 load64(const unsigned char* y) { u64 res = 0; for(int i = 0; i != 8; ++i) res |= (u64)(y[i]) << ((7-i) * 8); return res; } The load64 has been implemented by https://reviews.llvm.org/D26149 This patch is trying to implement the store pattern. Match a pattern where a wide type scalar value is stored by several narrow stores. Fold it into a single store or a BSWAP and a store if the targets supports it. Assuming little endian target: i8 *p = ... i32 val = ... p[0] = (val >> 0) & 0xFF; p[1] = (val >> 8) & 0xFF; p[2] = (val >> 16) & 0xFF; p[3] = (val >> 24) & 0xFF; > *((i32)p) = val; i8 *p = ... i32 val = ... p[0] = (val >> 24) & 0xFF; p[1] = (val >> 16) & 0xFF; p[2] = (val >> 8) & 0xFF; p[3] = (val >> 0) & 0xFF; > *((i32)p) = BSWAP(val); Differential Revision: https://reviews.llvm.org/D62897 llvm-svn: 362921
597 lines
20 KiB
LLVM
597 lines
20 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs < %s | FileCheck %s -check-prefix=CHECK-PPC64LE
|
|
; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 -verify-machineinstrs < %s | FileCheck %s -check-prefix=CHECK-PPC64
|
|
; i8* p;
|
|
; i32 m;
|
|
; p[0] = (m >> 0) & 0xFF;
|
|
; p[1] = (m >> 8) & 0xFF;
|
|
; p[2] = (m >> 16) & 0xFF;
|
|
; p[3] = (m >> 24) & 0xFF;
|
|
define void @store_i32_by_i8(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stw 3, 0(4)
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stwbrx 3, 0, 4
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%conv = trunc i32 %m to i8
|
|
store i8 %conv, i8* %p, align 1
|
|
%0 = lshr i32 %m, 8
|
|
%conv3 = trunc i32 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
ret void
|
|
}
|
|
; i8* p;
|
|
; i32 m;
|
|
; p[0] = (m >> 24) & 0xFF;
|
|
; p[1] = (m >> 16) & 0xFF;
|
|
; p[2] = (m >> 8) & 0xFF;
|
|
; p[3] = (m >> 0) & 0xFF;
|
|
define void @store_i32_by_i8_bswap(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stwbrx 3, 0, 4
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stw 3, 0(4)
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i32 %m, 24
|
|
%conv = trunc i32 %0 to i8
|
|
store i8 %conv, i8* %p, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv3 = trunc i32 %1 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%2 = lshr i32 %m, 8
|
|
%conv7 = trunc i32 %2 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%conv11 = trunc i32 %m to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
ret void
|
|
}
|
|
; i8 *p;
|
|
; i64 m;
|
|
; p[0] = (m >> 0) & 0xFF;
|
|
; p[1] = (m >> 8) & 0xFF;
|
|
; p[2] = (m >> 16) & 0xFF;
|
|
; p[3] = (m >> 24) & 0xFF;
|
|
; p[4] = (m >> 32) & 0xFF;
|
|
; p[5] = (m >> 40) & 0xFF;
|
|
; p[6] = (m >> 48) & 0xFF;
|
|
; p[7] = (m >> 56) & 0xFF;
|
|
define void @store_i64_by_i8(i64 %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i64_by_i8:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stdx 3, 0, 4
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i64_by_i8:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stdbrx 3, 0, 4
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%conv = trunc i64 %m to i8
|
|
store i8 %conv, i8* %p, align 1
|
|
%0 = lshr i64 %m, 8
|
|
%conv3 = trunc i64 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i64 %m, 16
|
|
%conv7 = trunc i64 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i64 %m, 24
|
|
%conv11 = trunc i64 %2 to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
%3 = lshr i64 %m, 32
|
|
%conv15 = trunc i64 %3 to i8
|
|
%arrayidx16 = getelementptr inbounds i8, i8* %p, i64 4
|
|
store i8 %conv15, i8* %arrayidx16, align 1
|
|
%4 = lshr i64 %m, 40
|
|
%conv19 = trunc i64 %4 to i8
|
|
%arrayidx20 = getelementptr inbounds i8, i8* %p, i64 5
|
|
store i8 %conv19, i8* %arrayidx20, align 1
|
|
%5 = lshr i64 %m, 48
|
|
%conv23 = trunc i64 %5 to i8
|
|
%arrayidx24 = getelementptr inbounds i8, i8* %p, i64 6
|
|
store i8 %conv23, i8* %arrayidx24, align 1
|
|
%6 = lshr i64 %m, 56
|
|
%conv27 = trunc i64 %6 to i8
|
|
%arrayidx28 = getelementptr inbounds i8, i8* %p, i64 7
|
|
store i8 %conv27, i8* %arrayidx28, align 1
|
|
ret void
|
|
}
|
|
; i8 *p;
|
|
; i64 m;
|
|
; p[7] = (m >> 0) & 0xFF;
|
|
; p[6] = (m >> 8) & 0xFF;
|
|
; p[5] = (m >> 16) & 0xFF;
|
|
; p[4] = (m >> 24) & 0xFF;
|
|
; p[3] = (m >> 32) & 0xFF;
|
|
; p[2] = (m >> 40) & 0xFF;
|
|
; p[1] = (m >> 48) & 0xFF;
|
|
; p[0] = (m >> 56) & 0xFF;
|
|
define void @store_i64_by_i8_bswap(i64 %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i64_by_i8_bswap:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stdbrx 3, 0, 4
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i64_by_i8_bswap:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stdx 3, 0, 4
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%conv = trunc i64 %m to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 7
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%0 = lshr i64 %m, 8
|
|
%conv3 = trunc i64 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 6
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i64 %m, 16
|
|
%conv7 = trunc i64 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 5
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i64 %m, 24
|
|
%conv11 = trunc i64 %2 to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 4
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
%3 = lshr i64 %m, 32
|
|
%conv15 = trunc i64 %3 to i8
|
|
%arrayidx16 = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv15, i8* %arrayidx16, align 1
|
|
%4 = lshr i64 %m, 40
|
|
%conv19 = trunc i64 %4 to i8
|
|
%arrayidx20 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv19, i8* %arrayidx20, align 1
|
|
%5 = lshr i64 %m, 48
|
|
%conv23 = trunc i64 %5 to i8
|
|
%arrayidx24 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv23, i8* %arrayidx24, align 1
|
|
%6 = lshr i64 %m, 56
|
|
%conv27 = trunc i64 %6 to i8
|
|
store i8 %conv27, i8* %p, align 1
|
|
ret void
|
|
}
|
|
|
|
; i32 t; i8 *p;
|
|
; i64 m = t * 7;
|
|
; p[7] = (m >> 0) & 0xFF;
|
|
; p[6] = (m >> 8) & 0xFF;
|
|
; p[5] = (m >> 16) & 0xFF;
|
|
; p[4] = (m >> 24) & 0xFF;
|
|
; p[3] = (m >> 32) & 0xFF;
|
|
; p[2] = (m >> 40) & 0xFF;
|
|
; p[1] = (m >> 48) & 0xFF;
|
|
; p[0] = (m >> 56) & 0xFF;
|
|
define void @store_i64_by_i8_bswap_uses(i32 signext %t, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i64_by_i8_bswap_uses:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: slwi [[REG:[0-9]+]], 3, 3
|
|
; CHECK-PPC64LE-NEXT: subf [[REG1:[0-9]+]], 3, [[REG]]
|
|
; CHECK-PPC64LE-NEXT: extsw [[REG2:[0-9]+]], [[REG1]]
|
|
; CHECK-PPC64LE-NEXT: stdbrx [[REG2]], 0, 4
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i64_by_i8_bswap_uses:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: slwi [[REG:[0-9]+]], 3, 3
|
|
; CHECK-PPC64-NEXT: subf [[REG1:[0-9]+]], 3, [[REG]]
|
|
; CHECK-PPC64-NEXT: extsw [[REG2:[0-9]+]], [[REG1]]
|
|
; CHECK-PPC64-NEXT: stdx [[REG2]], 0, 4
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%mul = mul nsw i32 %t, 7
|
|
%conv = sext i32 %mul to i64
|
|
%conv1 = trunc i32 %mul to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 7
|
|
store i8 %conv1, i8* %arrayidx, align 1
|
|
%0 = lshr i64 %conv, 8
|
|
%conv4 = trunc i64 %0 to i8
|
|
%arrayidx5 = getelementptr inbounds i8, i8* %p, i64 6
|
|
store i8 %conv4, i8* %arrayidx5, align 1
|
|
%1 = lshr i64 %conv, 16
|
|
%conv8 = trunc i64 %1 to i8
|
|
%arrayidx9 = getelementptr inbounds i8, i8* %p, i64 5
|
|
store i8 %conv8, i8* %arrayidx9, align 1
|
|
%2 = lshr i64 %conv, 24
|
|
%conv12 = trunc i64 %2 to i8
|
|
%arrayidx13 = getelementptr inbounds i8, i8* %p, i64 4
|
|
store i8 %conv12, i8* %arrayidx13, align 1
|
|
%shr14 = ashr i64 %conv, 32
|
|
%conv16 = trunc i64 %shr14 to i8
|
|
%arrayidx17 = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv16, i8* %arrayidx17, align 1
|
|
%shr18 = ashr i64 %conv, 40
|
|
%conv20 = trunc i64 %shr18 to i8
|
|
%arrayidx21 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv20, i8* %arrayidx21, align 1
|
|
%shr22 = ashr i64 %conv, 48
|
|
%conv24 = trunc i64 %shr22 to i8
|
|
%arrayidx25 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv24, i8* %arrayidx25, align 1
|
|
%shr26 = ashr i64 %conv, 56
|
|
%conv28 = trunc i64 %shr26 to i8
|
|
store i8 %conv28, i8* %p, align 1
|
|
ret void
|
|
; CEHCK-PPC64LE: stdbrx [[REG2]], 0, 4
|
|
; CEHCK-PPC64: stdx [[REG2]], 0, 4
|
|
}
|
|
|
|
; One of the stores is volatile
|
|
; i8 *p;
|
|
; p0 = volatile *p;
|
|
; p[3] = (m >> 0) & 0xFF;
|
|
; p[2] = (m >> 8) & 0xFF;
|
|
; p[1] = (m >> 16) & 0xFF;
|
|
; *p0 = (m >> 24) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_volatile(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_volatile:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NOT: stwbrx
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_volatile:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NOT: stw
|
|
entry:
|
|
%conv = trunc i32 %m to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%0 = lshr i32 %m, 8
|
|
%conv3 = trunc i32 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
store volatile i8 %conv11, i8* %p, align 1
|
|
ret void
|
|
}
|
|
|
|
; There is a store in between individual stores
|
|
; i8* p, q;
|
|
; p[3] = (m >> 0) & 0xFF;
|
|
; p[2] = (m >> 8) & 0xFF;
|
|
; *q = 3;
|
|
; p[1] = (m >> 16) & 0xFF;
|
|
; p[0] = (m >> 24) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_store_in_between(i32 signext %m, i8* %p, i8* %q) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_store_in_between:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NOT: stwbrx
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_store_in_between:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NOT: stw
|
|
entry:
|
|
%conv = trunc i32 %m to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%0 = lshr i32 %m, 8
|
|
%conv3 = trunc i32 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
store i8 3, i8* %q, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
store i8 %conv11, i8* %p, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @store_i32_by_i8_bswap_unrelated_store(i32 signext %m, i8* %p, i8* %q) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_unrelated_store:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NOT: stwbrx
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_unrelated_store:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NOT: stw
|
|
entry:
|
|
%conv = trunc i32 %m to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%0 = lshr i32 %m, 8
|
|
%conv3 = trunc i32 %0 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %q, i64 2
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
store i8 %conv11, i8* %p, align 1
|
|
ret void
|
|
}
|
|
; i32 m;
|
|
; i8* p;
|
|
; p[3] = (m >> 8) & 0xFF;
|
|
; p[4] = (m >> 0) & 0xFF;
|
|
; p[2] = (m >> 16) & 0xFF;
|
|
; p[1] = (m >> 24) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_nonzero_offset(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_nonzero_offset:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: addi [[REG1:[0-9]+]], 4, 1
|
|
; CHECK-PPC64LE-NEXT: stwbrx 3, 0, [[REG1]]
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_nonzero_offset:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stw 3, 1(4)
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i32 %m, 8
|
|
%conv = trunc i32 %0 to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%conv3 = trunc i32 %m to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 4
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
ret void
|
|
}
|
|
; i32 m;
|
|
; i8* p;
|
|
; p[-3] = (m >> 8) & 0xFF;
|
|
; p[-4] = (m >> 0) & 0xFF;
|
|
; p[-2] = (m >> 16) & 0xFF;
|
|
; p[-1] = (m >> 24) & 0xFF;
|
|
define void @store_i32_by_i8_neg_offset(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_neg_offset:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stw 3, -4(4)
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_neg_offset:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: addi [[REG1:[0-9]+]], 4, -4
|
|
; CHECK-PPC64-NEXT: stwbrx 3, 0, [[REG1]]
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i32 %m, 8
|
|
%conv = trunc i32 %0 to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 -3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%conv3 = trunc i32 %m to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 -4
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv7 = trunc i32 %1 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 -2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%2 = lshr i32 %m, 24
|
|
%conv11 = trunc i32 %2 to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 -1
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
ret void
|
|
}
|
|
; i32 m;
|
|
; i8* p;
|
|
; p[-3] = (m >> 16) & 0xFF;
|
|
; p[-4] = (m >> 24) & 0xFF;
|
|
; p[-2] = (m >> 8) & 0xFF;
|
|
; p[-1] = (m >> 0) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_neg_offset(i32 signext %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_neg_offset:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: addi [[REG1:[0-9]+]], 4, -4
|
|
; CHECK-PPC64LE-NEXT: stwbrx 3, 0, [[REG1]]
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_neg_offset:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stw 3, -4(4)
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i32 %m, 16
|
|
%conv = trunc i32 %0 to i8
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 -3
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%1 = lshr i32 %m, 24
|
|
%conv3 = trunc i32 %1 to i8
|
|
%arrayidx4 = getelementptr inbounds i8, i8* %p, i64 -4
|
|
store i8 %conv3, i8* %arrayidx4, align 1
|
|
%2 = lshr i32 %m, 8
|
|
%conv7 = trunc i32 %2 to i8
|
|
%arrayidx8 = getelementptr inbounds i8, i8* %p, i64 -2
|
|
store i8 %conv7, i8* %arrayidx8, align 1
|
|
%conv11 = trunc i32 %m to i8
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 -1
|
|
store i8 %conv11, i8* %arrayidx12, align 1
|
|
ret void
|
|
}
|
|
; i32 m, i;
|
|
; i8* p;
|
|
; p[i-3] = (m >> 16) & 0xFF;
|
|
; p[i-4] = (m >> 24) & 0xFF;
|
|
; p[i-2] = (m >> 8) & 0xFF;
|
|
; p[i-1] = (m >> 0) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_base_index_offset(i32 %m, i32 %i, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_base_index_offset:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: extsw [[REG1:[0-9]+]], 4
|
|
; CHECK-PPC64LE-NEXT: add [[REG2:[0-9]+]], 5, [[REG1]]
|
|
; CHECK-PPC64LE-NEXT: addi [[REG3:[0-9]+]], [[REG2]], -4
|
|
; CHECK-PPC64LE-NEXT: stwbrx 3, 0, [[REG3]]
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_base_index_offset:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: extsw [[REG1:[0-9]+]], 4
|
|
; CHECK-PPC64-NEXT: add [[REG2:[0-9]+]], 5, [[REG1]]
|
|
; CHECK-PPC64-NEXT: stw 3, -4([[REG2]])
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i32 %m, 16
|
|
%conv = trunc i32 %0 to i8
|
|
%sub = add nsw i32 %i, -3
|
|
%idxprom = sext i32 %sub to i64
|
|
%arrayidx = getelementptr inbounds i8, i8* %p, i64 %idxprom
|
|
store i8 %conv, i8* %arrayidx, align 1
|
|
%1 = lshr i32 %m, 24
|
|
%conv3 = trunc i32 %1 to i8
|
|
%sub4 = add nsw i32 %i, -4
|
|
%idxprom5 = sext i32 %sub4 to i64
|
|
%arrayidx6 = getelementptr inbounds i8, i8* %p, i64 %idxprom5
|
|
store i8 %conv3, i8* %arrayidx6, align 1
|
|
%2 = lshr i32 %m, 8
|
|
%conv9 = trunc i32 %2 to i8
|
|
%sub10 = add nsw i32 %i, -2
|
|
%idxprom11 = sext i32 %sub10 to i64
|
|
%arrayidx12 = getelementptr inbounds i8, i8* %p, i64 %idxprom11
|
|
store i8 %conv9, i8* %arrayidx12, align 1
|
|
%conv15 = trunc i32 %m to i8
|
|
%sub16 = add nsw i32 %i, -1
|
|
%idxprom17 = sext i32 %sub16 to i64
|
|
%arrayidx18 = getelementptr inbounds i8, i8* %p, i64 %idxprom17
|
|
store i8 %conv15, i8* %arrayidx18, align 1
|
|
ret void
|
|
}
|
|
|
|
; i8* p;
|
|
; i32 i, m;
|
|
; i8* p0 = p + i;
|
|
; i8* p1 = p + i + 1;
|
|
; i8* p2 = p + i + 2;
|
|
; i8 *p3 = p + i + 3;
|
|
; p0[3] = (m >> 24) & 0xFF;
|
|
; p1[3] = (m >> 16) & 0xFF;
|
|
; p2[3] = (m >> 8) & 0xFF;
|
|
; p3[3] = (m >> 0) & 0xFF;
|
|
define void @store_i32_by_i8_bswap_complicated(i32 %m, i32 %i, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i32_by_i8_bswap_complicated:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: extsw [[REG1:[0-9]+]], 4
|
|
; CHECK-PPC64LE-NEXT: add [[REG2:[0-9]+]], 5, [[REG1]]
|
|
; CHECK-PPC64LE-NEXT: addi [[REG3:[0-9]+]], [[REG2]], 3
|
|
; CHECK-PPC64LE-NEXT: stwbrx 3, 0, [[REG3]]
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i32_by_i8_bswap_complicated:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: extsw [[REG1:[0-9]+]], 4
|
|
; CHECK-PPC64-NEXT: add [[REG2:[0-9]+]], 5, [[REG1]]
|
|
; CHECK-PPC64-NEXT: stw 3, 3([[REG2]])
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%idx.ext = sext i32 %i to i64
|
|
%add.ptr = getelementptr inbounds i8, i8* %p, i64 %idx.ext
|
|
%add.ptr3 = getelementptr inbounds i8, i8* %add.ptr, i64 1
|
|
%add.ptr6 = getelementptr inbounds i8, i8* %add.ptr, i64 2
|
|
%add.ptr9 = getelementptr inbounds i8, i8* %add.ptr, i64 3
|
|
%0 = lshr i32 %m, 24
|
|
%conv = trunc i32 %0 to i8
|
|
store i8 %conv, i8* %add.ptr9, align 1
|
|
%1 = lshr i32 %m, 16
|
|
%conv12 = trunc i32 %1 to i8
|
|
%arrayidx13 = getelementptr inbounds i8, i8* %add.ptr3, i64 3
|
|
store i8 %conv12, i8* %arrayidx13, align 1
|
|
%2 = lshr i32 %m, 8
|
|
%conv16 = trunc i32 %2 to i8
|
|
%arrayidx17 = getelementptr inbounds i8, i8* %add.ptr6, i64 3
|
|
store i8 %conv16, i8* %arrayidx17, align 1
|
|
%conv20 = trunc i32 %m to i8
|
|
%arrayidx21 = getelementptr inbounds i8, i8* %add.ptr9, i64 3
|
|
store i8 %conv20, i8* %arrayidx21, align 1
|
|
ret void
|
|
}
|
|
; i8* p; i32 m;
|
|
; p[0] = (m >> 8) & 0xFF;
|
|
; p[1] = (m >> 0) & 0xFF;
|
|
define void @store_i16_by_i8_bswap(i16 %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_i16_by_i8_bswap:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: sthbrx 3, 0, 4
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_i16_by_i8_bswap:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: sth 3, 0(4)
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%0 = lshr i16 %m, 8
|
|
%conv1 = trunc i16 %0 to i8
|
|
store i8 %conv1, i8* %p, align 1
|
|
%conv5 = trunc i16 %m to i8
|
|
%arrayidx6 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv5, i8* %arrayidx6, align 1
|
|
ret void
|
|
}
|
|
; i8* p; i32 m;
|
|
; p[0] = (m >> 0) & 0xFF;
|
|
; p[1] = (m >> 8) & 0xFF;
|
|
define void @store_16_by_i8(i16 %m, i8* %p) {
|
|
; CHECK-PPC64LE-LABEL: store_16_by_i8:
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: sth 3, 0(4)
|
|
; CHECK-PPC64LE-NEXT: blr
|
|
;
|
|
; CHECK-PPC64-LABEL: store_16_by_i8:
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: sthbrx 3, 0, 4
|
|
; CHECK-PPC64-NEXT: blr
|
|
entry:
|
|
%conv1 = trunc i16 %m to i8
|
|
store i8 %conv1, i8* %p, align 1
|
|
%0 = lshr i16 %m, 8
|
|
%conv5 = trunc i16 %0 to i8
|
|
%arrayidx6 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %conv5, i8* %arrayidx6, align 1
|
|
ret void
|
|
}
|
|
; This was found when testing the hexxagon in testsuite
|
|
; i8* p; i8 v;
|
|
; p[0] = v;
|
|
; p[1] = v;
|
|
define void @store_same_value_to_consecutive_mem(i8* %p, i8 zeroext %v) {
|
|
; CHECK-PPC64LE-LABEL: store_same_value_to_consecutive_mem
|
|
; CHECK-PPC64LE: # %bb.0: # %entry
|
|
; CHECK-PPC64LE-NEXT: stb 4, 0(3)
|
|
; CHECK-PPC64LE-NEXT: stb 4, 1(3)
|
|
;
|
|
; CHECK-PPC64-LABEL: store_same_value_to_consecutive_mem
|
|
; CHECK-PPC64: # %bb.0: # %entry
|
|
; CHECK-PPC64-NEXT: stb 4, 0(3)
|
|
; CHECK-PPC64-NEXT: stb 4, 1(3)
|
|
entry:
|
|
store i8 %v, i8* %p, align 1
|
|
%arrayidx1 = getelementptr inbounds i8, i8* %p, i64 1
|
|
store i8 %v, i8* %arrayidx1, align 1
|
|
ret void
|
|
}
|