[MIPS GlobalISel] Legalize non-power-of-2 and unaligned load and store

Custom legalize non-power-of-2 and unaligned load and store for MIPS32r5
and older, custom legalize non-power-of-2 load and store for MIPS32r6.

Don't attempt to combine non power of 2 loads or unaligned loads when
subtarget doesn't support them (MIPS32r5 and older).

Differential Revision: https://reviews.llvm.org/D74625
This commit is contained in:
Petar Avramovic 2020-02-19 12:01:48 +01:00
parent 5171d1523d
commit 5e32e7981b
6 changed files with 3662 additions and 2 deletions

View File

@ -119,6 +119,33 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
return true;
return false;
})
// Custom lower scalar memory access, up to 8 bytes, for:
// - non-power-of-2 MemSizes
// - unaligned 2 or 8 byte MemSizes for MIPS32r5 and older
.customIf([=, &ST](const LegalityQuery &Query) {
if (!Query.Types[0].isScalar() || Query.Types[1] != p0 ||
Query.Types[0] == s1)
return false;
unsigned Size = Query.Types[0].getSizeInBits();
unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits;
assert(QueryMemSize <= Size && "Scalar can't hold MemSize");
if (Size > 64 || QueryMemSize > 64)
return false;
if (!isPowerOf2_64(Query.MMODescrs[0].SizeInBits))
return true;
if (!ST.systemSupportsUnalignedAccess() &&
isUnalignedMemmoryAccess(QueryMemSize,
Query.MMODescrs[0].AlignInBits)) {
assert(QueryMemSize != 32 && "4 byte load and store are legal");
return true;
}
return false;
})
.minScalar(0, s32);
getActionDefinitionsBuilder(G_IMPLICIT_DEF)
@ -135,7 +162,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
{s32, p0, 16, 8}})
.clampScalar(0, s32, s32);
getActionDefinitionsBuilder({G_ZEXT, G_SEXT})
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
.legalIf([](const LegalityQuery &Query) { return false; })
.maxScalar(0, s32);
@ -311,6 +338,87 @@ bool MipsLegalizerInfo::legalizeCustom(MachineInstr &MI,
const LLT s64 = LLT::scalar(64);
switch (MI.getOpcode()) {
case G_LOAD:
case G_STORE: {
unsigned MemSize = (**MI.memoperands_begin()).getSize();
Register Val = MI.getOperand(0).getReg();
unsigned Size = MRI.getType(Val).getSizeInBits();
MachineMemOperand *MMOBase = *MI.memoperands_begin();
assert(MemSize <= 8 && "MemSize is too large");
assert(Size <= 64 && "Scalar size is too large");
// Split MemSize into two, P2HalfMemSize is largest power of two smaller
// then MemSize. e.g. 8 = 4 + 4 , 6 = 4 + 2, 3 = 2 + 1.
unsigned P2HalfMemSize, RemMemSize;
if (isPowerOf2_64(MemSize)) {
P2HalfMemSize = RemMemSize = MemSize / 2;
} else {
P2HalfMemSize = 1 << Log2_32(MemSize);
RemMemSize = MemSize - P2HalfMemSize;
}
Register BaseAddr = MI.getOperand(1).getReg();
LLT PtrTy = MRI.getType(BaseAddr);
MachineFunction &MF = MIRBuilder.getMF();
auto P2HalfMemOp = MF.getMachineMemOperand(MMOBase, 0, P2HalfMemSize);
auto RemMemOp = MF.getMachineMemOperand(MMOBase, P2HalfMemSize, RemMemSize);
if (MI.getOpcode() == G_STORE) {
// Widen Val to s32 or s64 in order to create legal G_LSHR or G_UNMERGE.
if (Size < 32)
Val = MIRBuilder.buildAnyExt(s32, Val).getReg(0);
if (Size > 32 && Size < 64)
Val = MIRBuilder.buildAnyExt(s64, Val).getReg(0);
auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
if (MI.getOpcode() == G_STORE && MemSize <= 4) {
MIRBuilder.buildStore(Val, BaseAddr, *P2HalfMemOp);
auto C_P2Half_InBits = MIRBuilder.buildConstant(s32, P2HalfMemSize * 8);
auto Shift = MIRBuilder.buildLShr(s32, Val, C_P2Half_InBits);
MIRBuilder.buildStore(Shift, Addr, *RemMemOp);
} else {
auto Unmerge = MIRBuilder.buildUnmerge(s32, Val);
MIRBuilder.buildStore(Unmerge.getReg(0), BaseAddr, *P2HalfMemOp);
MIRBuilder.buildStore(Unmerge.getReg(1), Addr, *RemMemOp);
}
}
if (MI.getOpcode() == G_LOAD) {
if (MemSize <= 4) {
// This is anyextending load, use 4 byte lwr/lwl.
auto *Load4MMO = MF.getMachineMemOperand(MMOBase, 0, 4);
if (Size == 32)
MIRBuilder.buildLoad(Val, BaseAddr, *Load4MMO);
else {
auto Load = MIRBuilder.buildLoad(s32, BaseAddr, *Load4MMO);
MIRBuilder.buildTrunc(Val, Load.getReg(0));
}
} else {
auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
auto Load_P2Half = MIRBuilder.buildLoad(s32, BaseAddr, *P2HalfMemOp);
auto Load_Rem = MIRBuilder.buildLoad(s32, Addr, *RemMemOp);
if (Size == 64)
MIRBuilder.buildMerge(Val, {Load_P2Half, Load_Rem});
else {
auto Merge = MIRBuilder.buildMerge(s64, {Load_P2Half, Load_Rem});
MIRBuilder.buildTrunc(Val, Merge);
}
}
}
MI.eraseFromParent();
break;
}
case G_UITOFP: {
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();

View File

@ -44,9 +44,22 @@ bool MipsPreLegalizerCombinerInfo::combine(GISelChangeObserver &Observer,
return false;
case TargetOpcode::G_LOAD:
case TargetOpcode::G_SEXTLOAD:
case TargetOpcode::G_ZEXTLOAD:
case TargetOpcode::G_ZEXTLOAD: {
// Don't attempt to combine non power of 2 loads or unaligned loads when
// subtarget doesn't support them.
auto MMO = *MI.memoperands_begin();
const MipsSubtarget &STI =
static_cast<const MipsSubtarget &>(MI.getMF()->getSubtarget());
if (!isPowerOf2_64(MMO->getSize()))
return false;
bool isUnaligned = MMO->getSize() > MMO->getAlignment();
if (!STI.systemSupportsUnalignedAccess() && isUnaligned)
return false;
return Helper.tryCombineExtendingLoads(MI);
}
}
return false;
}

View File

@ -0,0 +1,692 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -mcpu=mips32r6 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32R6
%struct.MemSize3_Align1 = type { [3 x i8], i8 }
%struct.MemSize3_Align2 = type { [3 x i8], i8 }
%struct.MemSize3_Align4 = type { [3 x i8], i8 }
%struct.MemSize3_Align8 = type { [3 x i8], i8, [4 x i8] }
%struct.MemSize5_Align1 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align2 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align4 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align8 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize6_Align1 = type { [6 x i8], i16 }
%struct.MemSize6_Align2 = type { [6 x i8], i16 }
%struct.MemSize6_Align4 = type { [6 x i8], i16 }
%struct.MemSize6_Align8 = type { [6 x i8], i16 }
%struct.MemSize7_Align1 = type { [7 x i8], i8 }
%struct.MemSize7_Align2 = type { [7 x i8], i8 }
%struct.MemSize7_Align4 = type { [7 x i8], i8 }
%struct.MemSize7_Align8 = type { [7 x i8], i8 }
@double_align1 = common global double 0.000000e+00, align 1
@double_align2 = common global double 0.000000e+00, align 2
@double_align4 = common global double 0.000000e+00, align 4
@double_align8 = common global double 0.000000e+00, align 8
@i64_align1 = common global i64 0, align 1
@i64_align2 = common global i64 0, align 2
@i64_align4 = common global i64 0, align 4
@i64_align8 = common global i64 0, align 8
define i32 @load3align1(%struct.MemSize3_Align1* %S) {
; MIPS32-LABEL: load3align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: lui $2, 255
; MIPS32-NEXT: ori $2, $2, 65535
; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load3align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lui $2, 255
; MIPS32R6-NEXT: ori $2, $2, 65535
; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align1* %S to i24*
%bf.load = load i24, i24* %0, align 1
%bf.cast = zext i24 %bf.load to i32
ret i32 %bf.cast
}
define i32 @load3align2(%struct.MemSize3_Align2* %S) {
; MIPS32-LABEL: load3align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: lui $2, 255
; MIPS32-NEXT: ori $2, $2, 65535
; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load3align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lui $2, 255
; MIPS32R6-NEXT: ori $2, $2, 65535
; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align2* %S to i24*
%bf.load = load i24, i24* %0, align 2
%bf.cast = zext i24 %bf.load to i32
ret i32 %bf.cast
}
define i32 @load3align4(%struct.MemSize3_Align4* %S, i32 signext %a) {
; MIPS32-LABEL: load3align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lui $2, 255
; MIPS32-NEXT: ori $2, $2, 65535
; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load3align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lui $2, 255
; MIPS32R6-NEXT: ori $2, $2, 65535
; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align4* %S to i24*
%bf.load = load i24, i24* %0, align 4
%bf.cast = zext i24 %bf.load to i32
ret i32 %bf.cast
}
define i32 @load3align8(%struct.MemSize3_Align8* %S, i32 signext %a) {
; MIPS32-LABEL: load3align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lui $2, 255
; MIPS32-NEXT: ori $2, $2, 65535
; MIPS32-NEXT: and $2, $1, $2
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load3align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lui $2, 255
; MIPS32R6-NEXT: ori $2, $2, 65535
; MIPS32R6-NEXT: and $2, $1, $2
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align8* %S to i24*
%bf.load = load i24, i24* %0, align 8
%bf.cast = zext i24 %bf.load to i32
ret i32 %bf.cast
}
define i64 @load5align1(%struct.MemSize5_Align1* %S) {
; MIPS32-LABEL: load5align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: lbu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 255
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load5align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lbu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 255
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align1* %S to i40*
%bf.load = load i40, i40* %0, align 1
%bf.cast = zext i40 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load5align2(%struct.MemSize5_Align2* %S) {
; MIPS32-LABEL: load5align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: lbu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 255
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load5align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lbu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 255
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align2* %S to i40*
%bf.load = load i40, i40* %0, align 2
%bf.cast = zext i40 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load5align4(%struct.MemSize5_Align4* %S) {
; MIPS32-LABEL: load5align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lbu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 255
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load5align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lbu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 255
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align4* %S to i40*
%bf.load = load i40, i40* %0, align 4
%bf.cast = zext i40 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load5align8(%struct.MemSize5_Align8* %S) {
; MIPS32-LABEL: load5align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lbu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 255
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load5align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lbu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 255
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align8* %S to i40*
%bf.load = load i40, i40* %0, align 8
%bf.cast = zext i40 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load6align1(%struct.MemSize6_Align1* %S) {
; MIPS32-LABEL: load6align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 7($4)
; MIPS32-NEXT: lwr $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 65535
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load6align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lhu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 65535
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align1* %S to i48*
%bf.load = load i48, i48* %0, align 1
%bf.cast = zext i48 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load6align2(%struct.MemSize6_Align2* %S) {
; MIPS32-LABEL: load6align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: lhu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 65535
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load6align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lhu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 65535
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align2* %S to i48*
%bf.load = load i48, i48* %0, align 2
%bf.cast = zext i48 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load6align4(%struct.MemSize6_Align4* %S) {
; MIPS32-LABEL: load6align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lhu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 65535
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load6align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lhu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 65535
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align4* %S to i48*
%bf.load = load i48, i48* %0, align 4
%bf.cast = zext i48 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load6align8(%struct.MemSize6_Align8* %S) {
; MIPS32-LABEL: load6align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lhu $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: andi $3, $2, 65535
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load6align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lhu $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: andi $3, $2, 65535
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align8* %S to i48*
%bf.load = load i48, i48* %0, align 8
%bf.cast = zext i48 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load7align1(%struct.MemSize7_Align1* %S) {
; MIPS32-LABEL: load7align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 7($4)
; MIPS32-NEXT: lwr $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: lui $4, 255
; MIPS32-NEXT: ori $4, $4, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: and $3, $2, $4
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load7align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lw $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: lui $4, 255
; MIPS32R6-NEXT: ori $4, $4, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: and $3, $2, $4
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align1* %S to i56*
%bf.load = load i56, i56* %0, align 1
%bf.cast = zext i56 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load7align2(%struct.MemSize7_Align2* %S) {
; MIPS32-LABEL: load7align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: # implicit-def: $at
; MIPS32-NEXT: lwl $1, 3($4)
; MIPS32-NEXT: lwr $1, 0($4)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 7($4)
; MIPS32-NEXT: lwr $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: lui $4, 255
; MIPS32-NEXT: ori $4, $4, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: and $3, $2, $4
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load7align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lw $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: lui $4, 255
; MIPS32R6-NEXT: ori $4, $4, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: and $3, $2, $4
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align2* %S to i56*
%bf.load = load i56, i56* %0, align 2
%bf.cast = zext i56 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load7align4(%struct.MemSize7_Align4* %S) {
; MIPS32-LABEL: load7align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lw $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: lui $4, 255
; MIPS32-NEXT: ori $4, $4, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: and $3, $2, $4
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load7align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lw $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: lui $4, 255
; MIPS32R6-NEXT: ori $4, $4, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: and $3, $2, $4
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align4* %S to i56*
%bf.load = load i56, i56* %0, align 4
%bf.cast = zext i56 %bf.load to i64
ret i64 %bf.cast
}
define i64 @load7align8(%struct.MemSize7_Align8* %S) {
; MIPS32-LABEL: load7align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lw $1, 0($4)
; MIPS32-NEXT: lw $2, 4($4)
; MIPS32-NEXT: addiu $3, $zero, 65535
; MIPS32-NEXT: lui $4, 255
; MIPS32-NEXT: ori $4, $4, 65535
; MIPS32-NEXT: and $1, $1, $3
; MIPS32-NEXT: and $3, $2, $4
; MIPS32-NEXT: move $2, $1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load7align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lw $1, 0($4)
; MIPS32R6-NEXT: lw $2, 4($4)
; MIPS32R6-NEXT: addiu $3, $zero, 65535
; MIPS32R6-NEXT: lui $4, 255
; MIPS32R6-NEXT: ori $4, $4, 65535
; MIPS32R6-NEXT: and $1, $1, $3
; MIPS32R6-NEXT: and $3, $2, $4
; MIPS32R6-NEXT: move $2, $1
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align8* %S to i56*
%bf.load = load i56, i56* %0, align 8
%bf.cast = zext i56 %bf.load to i64
ret i64 %bf.cast
}
define double @load_double_align1() {
; MIPS32-LABEL: load_double_align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align1)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align1)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 3($1)
; MIPS32-NEXT: lwr $2, 0($1)
; MIPS32-NEXT: # implicit-def: $v1
; MIPS32-NEXT: lwl $3, 7($1)
; MIPS32-NEXT: lwr $3, 4($1)
; MIPS32-NEXT: mtc1 $2, $f0
; MIPS32-NEXT: mtc1 $3, $f1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_double_align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align1)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align1)
; MIPS32R6-NEXT: ldc1 $f0, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load double, double* @double_align1, align 1
ret double %0
}
define double @load_double_align2() {
; MIPS32-LABEL: load_double_align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align2)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align2)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 3($1)
; MIPS32-NEXT: lwr $2, 0($1)
; MIPS32-NEXT: # implicit-def: $v1
; MIPS32-NEXT: lwl $3, 7($1)
; MIPS32-NEXT: lwr $3, 4($1)
; MIPS32-NEXT: mtc1 $2, $f0
; MIPS32-NEXT: mtc1 $3, $f1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_double_align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align2)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align2)
; MIPS32R6-NEXT: ldc1 $f0, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load double, double* @double_align2, align 2
ret double %0
}
define double @load_double_align4() {
; MIPS32-LABEL: load_double_align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align4)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align4)
; MIPS32-NEXT: lw $2, 0($1)
; MIPS32-NEXT: lw $1, 4($1)
; MIPS32-NEXT: mtc1 $2, $f0
; MIPS32-NEXT: mtc1 $1, $f1
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_double_align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align4)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align4)
; MIPS32R6-NEXT: ldc1 $f0, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load double, double* @double_align4, align 4
ret double %0
}
define double @load_double_align8() {
; MIPS32-LABEL: load_double_align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align8)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align8)
; MIPS32-NEXT: ldc1 $f0, 0($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_double_align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align8)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align8)
; MIPS32R6-NEXT: ldc1 $f0, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load double, double* @double_align8, align 8
ret double %0
}
define i64 @load_i64_align1() {
; MIPS32-LABEL: load_i64_align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align1)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align1)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 3($1)
; MIPS32-NEXT: lwr $2, 0($1)
; MIPS32-NEXT: # implicit-def: $v1
; MIPS32-NEXT: lwl $3, 7($1)
; MIPS32-NEXT: lwr $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_i64_align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align1)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align1)
; MIPS32R6-NEXT: lw $2, 0($1)
; MIPS32R6-NEXT: lw $3, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load i64, i64* @i64_align1, align 1
ret i64 %0
}
define i64 @load_i64_align2() {
; MIPS32-LABEL: load_i64_align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align2)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align2)
; MIPS32-NEXT: # implicit-def: $v0
; MIPS32-NEXT: lwl $2, 3($1)
; MIPS32-NEXT: lwr $2, 0($1)
; MIPS32-NEXT: # implicit-def: $v1
; MIPS32-NEXT: lwl $3, 7($1)
; MIPS32-NEXT: lwr $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_i64_align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align2)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align2)
; MIPS32R6-NEXT: lw $2, 0($1)
; MIPS32R6-NEXT: lw $3, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load i64, i64* @i64_align2, align 2
ret i64 %0
}
define i64 @load_i64_align4() {
; MIPS32-LABEL: load_i64_align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align4)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align4)
; MIPS32-NEXT: lw $2, 0($1)
; MIPS32-NEXT: lw $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_i64_align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align4)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align4)
; MIPS32R6-NEXT: lw $2, 0($1)
; MIPS32R6-NEXT: lw $3, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load i64, i64* @i64_align4, align 4
ret i64 %0
}
define i64 @load_i64_align8() {
; MIPS32-LABEL: load_i64_align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align8)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align8)
; MIPS32-NEXT: lw $2, 0($1)
; MIPS32-NEXT: lw $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: load_i64_align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align8)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align8)
; MIPS32R6-NEXT: lw $2, 0($1)
; MIPS32R6-NEXT: lw $3, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = load i64, i64* @i64_align8, align 8
ret i64 %0
}

View File

@ -0,0 +1,588 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -mcpu=mips32r6 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32R6
%struct.MemSize3_Align1 = type { [3 x i8], i8 }
%struct.MemSize3_Align2 = type { [3 x i8], i8 }
%struct.MemSize3_Align4 = type { [3 x i8], i8 }
%struct.MemSize3_Align8 = type { [3 x i8], i8, [4 x i8] }
%struct.MemSize5_Align1 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align2 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align4 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize5_Align8 = type <{ [5 x i8], i16, i8 }>
%struct.MemSize6_Align1 = type { [6 x i8], i16 }
%struct.MemSize6_Align2 = type { [6 x i8], i16 }
%struct.MemSize6_Align4 = type { [6 x i8], i16 }
%struct.MemSize6_Align8 = type { [6 x i8], i16 }
%struct.MemSize7_Align1 = type { [7 x i8], i8 }
%struct.MemSize7_Align2 = type { [7 x i8], i8 }
%struct.MemSize7_Align4 = type { [7 x i8], i8 }
%struct.MemSize7_Align8 = type { [7 x i8], i8 }
@double_align1 = common global double 0.000000e+00, align 1
@double_align2 = common global double 0.000000e+00, align 2
@double_align4 = common global double 0.000000e+00, align 4
@double_align8 = common global double 0.000000e+00, align 8
@i64_align1 = common global i64 0, align 1
@i64_align2 = common global i64 0, align 2
@i64_align4 = common global i64 0, align 4
@i64_align8 = common global i64 0, align 8
define void @store3align1(%struct.MemSize3_Align1* %S, i32 signext %a) {
; MIPS32-LABEL: store3align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sb $5, 0($4)
; MIPS32-NEXT: srl $1, $5, 8
; MIPS32-NEXT: sb $1, 1($4)
; MIPS32-NEXT: srl $1, $5, 16
; MIPS32-NEXT: sb $1, 2($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store3align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sh $5, 0($4)
; MIPS32R6-NEXT: srl $1, $5, 16
; MIPS32R6-NEXT: sb $1, 2($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align1* %S to i24*
%1 = trunc i32 %a to i24
store i24 %1, i24* %0, align 1
ret void
}
define void @store3align2(%struct.MemSize3_Align2* %S, i32 signext %a) {
; MIPS32-LABEL: store3align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sh $5, 0($4)
; MIPS32-NEXT: srl $1, $5, 16
; MIPS32-NEXT: sb $1, 2($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store3align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sh $5, 0($4)
; MIPS32R6-NEXT: srl $1, $5, 16
; MIPS32R6-NEXT: sb $1, 2($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align2* %S to i24*
%1 = trunc i32 %a to i24
store i24 %1, i24* %0, align 2
ret void
}
define void @store3align4(%struct.MemSize3_Align4* %S, i32 signext %a) {
; MIPS32-LABEL: store3align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sh $5, 0($4)
; MIPS32-NEXT: srl $1, $5, 16
; MIPS32-NEXT: sb $1, 2($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store3align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sh $5, 0($4)
; MIPS32R6-NEXT: srl $1, $5, 16
; MIPS32R6-NEXT: sb $1, 2($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align4* %S to i24*
%1 = trunc i32 %a to i24
store i24 %1, i24* %0, align 4
ret void
}
define void @store3align8(%struct.MemSize3_Align8* %S, i32 signext %a) {
; MIPS32-LABEL: store3align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sh $5, 0($4)
; MIPS32-NEXT: srl $1, $5, 16
; MIPS32-NEXT: sb $1, 2($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store3align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sh $5, 0($4)
; MIPS32R6-NEXT: srl $1, $5, 16
; MIPS32R6-NEXT: sb $1, 2($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize3_Align8* %S to i24*
%1 = trunc i32 %a to i24
store i24 %1, i24* %0, align 8
ret void
}
define void @store5align1(%struct.MemSize5_Align1* %S, i64 %a) {
; MIPS32-LABEL: store5align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store5align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sb $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align1* %S to i40*
%1 = trunc i64 %a to i40
store i40 %1, i40* %0, align 1
ret void
}
define void @store5align2(%struct.MemSize5_Align2* %S, i64 %a) {
; MIPS32-LABEL: store5align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store5align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sb $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align2* %S to i40*
%1 = trunc i64 %a to i40
store i40 %1, i40* %0, align 2
ret void
}
define void @store5align4(%struct.MemSize5_Align4* %S, i64 %a) {
; MIPS32-LABEL: store5align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store5align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sb $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align4* %S to i40*
%1 = trunc i64 %a to i40
store i40 %1, i40* %0, align 4
ret void
}
define void @store5align8(%struct.MemSize5_Align8* %S, i64 %a) {
; MIPS32-LABEL: store5align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store5align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sb $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize5_Align8* %S to i40*
%1 = trunc i64 %a to i40
store i40 %1, i40* %0, align 8
ret void
}
define void @store6align1(%struct.MemSize6_Align1* %S, i64 %a) {
; MIPS32-LABEL: store6align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: ori $1, $zero, 4
; MIPS32-NEXT: addu $1, $4, $1
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: srl $2, $7, 8
; MIPS32-NEXT: sb $2, 1($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store6align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align1* %S to i48*
%1 = trunc i64 %a to i48
store i48 %1, i48* %0, align 1
ret void
}
define void @store6align2(%struct.MemSize6_Align2* %S, i64 %a) {
; MIPS32-LABEL: store6align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store6align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align2* %S to i48*
%1 = trunc i64 %a to i48
store i48 %1, i48* %0, align 2
ret void
}
define void @store6align4(%struct.MemSize6_Align4* %S, i64 %a) {
; MIPS32-LABEL: store6align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store6align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align4* %S to i48*
%1 = trunc i64 %a to i48
store i48 %1, i48* %0, align 4
ret void
}
define void @store6align8(%struct.MemSize6_Align8* %S, i64 %a) {
; MIPS32-LABEL: store6align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store6align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize6_Align8* %S to i48*
%1 = trunc i64 %a to i48
store i48 %1, i48* %0, align 8
ret void
}
define void @store7align1(%struct.MemSize7_Align1* %S, i64 %a) {
; MIPS32-LABEL: store7align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: ori $1, $zero, 4
; MIPS32-NEXT: addu $1, $4, $1
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sb $7, 4($4)
; MIPS32-NEXT: srl $2, $7, 8
; MIPS32-NEXT: sb $2, 1($1)
; MIPS32-NEXT: srl $2, $7, 16
; MIPS32-NEXT: sb $2, 2($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store7align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: ori $1, $zero, 4
; MIPS32R6-NEXT: addu $1, $4, $1
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: srl $2, $7, 16
; MIPS32R6-NEXT: sb $2, 2($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align1* %S to i56*
%1 = trunc i64 %a to i56
store i56 %1, i56* %0, align 1
ret void
}
define void @store7align2(%struct.MemSize7_Align2* %S, i64 %a) {
; MIPS32-LABEL: store7align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: ori $1, $zero, 4
; MIPS32-NEXT: addu $1, $4, $1
; MIPS32-NEXT: swl $6, 3($4)
; MIPS32-NEXT: swr $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: srl $2, $7, 16
; MIPS32-NEXT: sb $2, 2($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store7align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: ori $1, $zero, 4
; MIPS32R6-NEXT: addu $1, $4, $1
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: srl $2, $7, 16
; MIPS32R6-NEXT: sb $2, 2($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align2* %S to i56*
%1 = trunc i64 %a to i56
store i56 %1, i56* %0, align 2
ret void
}
define void @store7align4(%struct.MemSize7_Align4* %S, i64 %a) {
; MIPS32-LABEL: store7align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: ori $1, $zero, 4
; MIPS32-NEXT: addu $1, $4, $1
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: srl $2, $7, 16
; MIPS32-NEXT: sb $2, 2($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store7align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: ori $1, $zero, 4
; MIPS32R6-NEXT: addu $1, $4, $1
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: srl $2, $7, 16
; MIPS32R6-NEXT: sb $2, 2($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align4* %S to i56*
%1 = trunc i64 %a to i56
store i56 %1, i56* %0, align 4
ret void
}
define void @store7align8(%struct.MemSize7_Align8* %S, i64 %a) {
; MIPS32-LABEL: store7align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: ori $1, $zero, 4
; MIPS32-NEXT: addu $1, $4, $1
; MIPS32-NEXT: sw $6, 0($4)
; MIPS32-NEXT: sh $7, 4($4)
; MIPS32-NEXT: srl $2, $7, 16
; MIPS32-NEXT: sb $2, 2($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store7align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: ori $1, $zero, 4
; MIPS32R6-NEXT: addu $1, $4, $1
; MIPS32R6-NEXT: sw $6, 0($4)
; MIPS32R6-NEXT: sh $7, 4($4)
; MIPS32R6-NEXT: srl $2, $7, 16
; MIPS32R6-NEXT: sb $2, 2($1)
; MIPS32R6-NEXT: jrc $ra
entry:
%0 = bitcast %struct.MemSize7_Align8* %S to i56*
%1 = trunc i64 %a to i56
store i56 %1, i56* %0, align 8
ret void
}
define void @store_double_align1(double %a) {
; MIPS32-LABEL: store_double_align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align1)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align1)
; MIPS32-NEXT: mfc1 $2, $f12
; MIPS32-NEXT: mfc1 $3, $f13
; MIPS32-NEXT: swl $2, 3($1)
; MIPS32-NEXT: swr $2, 0($1)
; MIPS32-NEXT: swl $3, 7($1)
; MIPS32-NEXT: swr $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_double_align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align1)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align1)
; MIPS32R6-NEXT: sdc1 $f12, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store double %a, double* @double_align1, align 1
ret void
}
define void @store_double_align2(double %a) {
; MIPS32-LABEL: store_double_align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align2)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align2)
; MIPS32-NEXT: mfc1 $2, $f12
; MIPS32-NEXT: mfc1 $3, $f13
; MIPS32-NEXT: swl $2, 3($1)
; MIPS32-NEXT: swr $2, 0($1)
; MIPS32-NEXT: swl $3, 7($1)
; MIPS32-NEXT: swr $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_double_align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align2)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align2)
; MIPS32R6-NEXT: sdc1 $f12, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store double %a, double* @double_align2, align 2
ret void
}
define void @store_double_align4(double %a) {
; MIPS32-LABEL: store_double_align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align4)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align4)
; MIPS32-NEXT: mfc1 $2, $f12
; MIPS32-NEXT: mfc1 $3, $f13
; MIPS32-NEXT: sw $2, 0($1)
; MIPS32-NEXT: sw $3, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_double_align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align4)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align4)
; MIPS32R6-NEXT: sdc1 $f12, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store double %a, double* @double_align4, align 4
ret void
}
define void @store_double_align8(double %a) {
; MIPS32-LABEL: store_double_align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(double_align8)
; MIPS32-NEXT: addiu $1, $1, %lo(double_align8)
; MIPS32-NEXT: sdc1 $f12, 0($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_double_align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(double_align8)
; MIPS32R6-NEXT: addiu $1, $1, %lo(double_align8)
; MIPS32R6-NEXT: sdc1 $f12, 0($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store double %a, double* @double_align8, align 8
ret void
}
define void @store_i64_align1(i64 %a) {
; MIPS32-LABEL: store_i64_align1:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align1)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align1)
; MIPS32-NEXT: swl $4, 3($1)
; MIPS32-NEXT: swr $4, 0($1)
; MIPS32-NEXT: swl $5, 7($1)
; MIPS32-NEXT: swr $5, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_i64_align1:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align1)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align1)
; MIPS32R6-NEXT: sw $4, 0($1)
; MIPS32R6-NEXT: sw $5, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store i64 %a, i64* @i64_align1, align 1
ret void
}
define void @store_i64_align2(i64 signext %a) {
; MIPS32-LABEL: store_i64_align2:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align2)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align2)
; MIPS32-NEXT: swl $4, 3($1)
; MIPS32-NEXT: swr $4, 0($1)
; MIPS32-NEXT: swl $5, 7($1)
; MIPS32-NEXT: swr $5, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_i64_align2:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align2)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align2)
; MIPS32R6-NEXT: sw $4, 0($1)
; MIPS32R6-NEXT: sw $5, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store i64 %a, i64* @i64_align2, align 2
ret void
}
define void @store_i64_align4(i64 %a) {
; MIPS32-LABEL: store_i64_align4:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align4)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align4)
; MIPS32-NEXT: sw $4, 0($1)
; MIPS32-NEXT: sw $5, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_i64_align4:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align4)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align4)
; MIPS32R6-NEXT: sw $4, 0($1)
; MIPS32R6-NEXT: sw $5, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store i64 %a, i64* @i64_align4, align 4
ret void
}
define void @store_i64_align8(i64 signext %a) {
; MIPS32-LABEL: store_i64_align8:
; MIPS32: # %bb.0: # %entry
; MIPS32-NEXT: lui $1, %hi(i64_align8)
; MIPS32-NEXT: addiu $1, $1, %lo(i64_align8)
; MIPS32-NEXT: sw $4, 0($1)
; MIPS32-NEXT: sw $5, 4($1)
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
;
; MIPS32R6-LABEL: store_i64_align8:
; MIPS32R6: # %bb.0: # %entry
; MIPS32R6-NEXT: lui $1, %hi(i64_align8)
; MIPS32R6-NEXT: addiu $1, $1, %lo(i64_align8)
; MIPS32R6-NEXT: sw $4, 0($1)
; MIPS32R6-NEXT: sw $5, 4($1)
; MIPS32R6-NEXT: jrc $ra
entry:
store i64 %a, i64* @i64_align8, align 8
ret void
}