[llvm] 5171d15 - [MIPS GlobalISel] Select 4 byte unaligned load and store
Petar Avramovic via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 19 02:57:41 PST 2020
Author: Petar Avramovic
Date: 2020-02-19T11:57:06+01:00
New Revision: 5171d1523dd853117d0df080850d1c77c63d0e76
URL: https://github.com/llvm/llvm-project/commit/5171d1523dd853117d0df080850d1c77c63d0e76
DIFF: https://github.com/llvm/llvm-project/commit/5171d1523dd853117d0df080850d1c77c63d0e76.diff
LOG: [MIPS GlobalISel] Select 4 byte unaligned load and store
Improve legality checks for load and store, 4 byte scalar
load and store are now legal for all subtargets.
During regbank selection 4 byte unaligned loads and stores
for MIPS32r5 and older get mapped to gprb.
Select 4 byte unaligned loads and stores for MIPS32r5.
Fix tests that unintentionally had unaligned load or store.
Differential Revision: https://reviews.llvm.org/D74624
Added:
llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned.mir
llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned_r6.mir
llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned.mir
llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned_r6.mir
llvm/test/CodeGen/Mips/GlobalISel/legalizer/load_4_unaligned.mir
llvm/test/CodeGen/Mips/GlobalISel/legalizer/store_4_unaligned.mir
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_4_unaligned.ll
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/store_4_unaligned.ll
llvm/test/CodeGen/Mips/GlobalISel/regbankselect/load_4_unaligned.mir
llvm/test/CodeGen/Mips/GlobalISel/regbankselect/store_4_unaligned.mir
Modified:
llvm/lib/Target/Mips/MipsInstructionSelector.cpp
llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 81acbb7adeee..1a25f84abb72 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -49,6 +49,12 @@ class MipsInstructionSelector : public InstructionSelector {
getRegClassForTypeOnBank(Register Reg, MachineRegisterInfo &MRI) const;
unsigned selectLoadStoreOpCode(MachineInstr &I,
MachineRegisterInfo &MRI) const;
+ bool buildUnalignedStore(MachineInstr &I, unsigned Opc,
+ MachineOperand &BaseAddr, unsigned Offset,
+ MachineMemOperand *MMO) const;
+ bool buildUnalignedLoad(MachineInstr &I, unsigned Opc, Register Dest,
+ MachineOperand &BaseAddr, unsigned Offset,
+ Register TiedDest, MachineMemOperand *MMO) const;
const MipsTargetMachine &TM;
const MipsSubtarget &STI;
@@ -248,6 +254,35 @@ MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
return Opc;
}
+bool MipsInstructionSelector::buildUnalignedStore(
+ MachineInstr &I, unsigned Opc, MachineOperand &BaseAddr, unsigned Offset,
+ MachineMemOperand *MMO) const {
+ MachineInstr *NewInst =
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
+ .add(I.getOperand(0))
+ .add(BaseAddr)
+ .addImm(Offset)
+ .addMemOperand(MMO);
+ if (!constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI))
+ return false;
+ return true;
+}
+
+bool MipsInstructionSelector::buildUnalignedLoad(
+ MachineInstr &I, unsigned Opc, Register Dest, MachineOperand &BaseAddr,
+ unsigned Offset, Register TiedDest, MachineMemOperand *MMO) const {
+ MachineInstr *NewInst =
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opc))
+ .addDef(Dest)
+ .add(BaseAddr)
+ .addImm(Offset)
+ .addUse(TiedDest)
+ .addMemOperand(*I.memoperands_begin());
+ if (!constrainSelectedInstRegOperands(*NewInst, TII, TRI, RBI))
+ return false;
+ return true;
+}
+
bool MipsInstructionSelector::select(MachineInstr &I) {
MachineBasicBlock &MBB = *I.getParent();
@@ -404,10 +439,7 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
case G_LOAD:
case G_ZEXTLOAD:
case G_SEXTLOAD: {
- const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
- if (NewOpc == I.getOpcode())
- return false;
-
+ auto MMO = *I.memoperands_begin();
MachineOperand BaseAddr = I.getOperand(1);
int64_t SignedOffset = 0;
// Try to fold load/store + G_PTR_ADD + G_CONSTANT
@@ -429,11 +461,48 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
}
}
+ // Unaligned memory access
+ if (MMO->getSize() > MMO->getAlignment() &&
+ !STI.systemSupportsUnalignedAccess()) {
+ if (MMO->getSize() != 4 || !isRegInGprb(I.getOperand(0).getReg(), MRI))
+ return false;
+
+ if (I.getOpcode() == G_STORE) {
+ if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, SignedOffset + 3, MMO))
+ return false;
+ if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, SignedOffset, MMO))
+ return false;
+ I.eraseFromParent();
+ return true;
+ }
+
+ if (I.getOpcode() == G_LOAD) {
+ Register ImplDef = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+ BuildMI(MBB, I, I.getDebugLoc(), TII.get(Mips::IMPLICIT_DEF))
+ .addDef(ImplDef);
+ Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);
+ if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, SignedOffset + 3,
+ ImplDef, MMO))
+ return false;
+ if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
+ BaseAddr, SignedOffset, Tmp, MMO))
+ return false;
+ I.eraseFromParent();
+ return true;
+ }
+
+ return false;
+ }
+
+ const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
+ if (NewOpc == I.getOpcode())
+ return false;
+
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
.add(I.getOperand(0))
.add(BaseAddr)
.addImm(SignedOffset)
- .addMemOperand(*I.memoperands_begin());
+ .addMemOperand(MMO);
break;
}
case G_UDIV:
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index d9309661efc3..09498952bcf8 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -21,22 +21,38 @@ struct TypesAndMemOps {
LLT ValTy;
LLT PtrTy;
unsigned MemSize;
- bool MustBeNaturallyAligned;
+ bool SystemSupportsUnalignedAccess;
};
+// Assumes power of 2 memory size. Subtargets that have only naturally-aligned
+// memory access need to perform additional legalization here.
+bool isUnalignedMemmoryAccess(uint64_t MemSize, uint64_t AlignInBits) {
+ assert(isPowerOf2_64(MemSize) && "Expected power of 2 memory size");
+ assert(isPowerOf2_64(AlignInBits) && "Expected power of 2 align");
+ if (MemSize > AlignInBits)
+ return true;
+ return false;
+}
+
static bool
CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query,
std::initializer_list<TypesAndMemOps> SupportedValues) {
+ unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits;
+
+ // Non power of two memory access is never legal.
+ if (!isPowerOf2_64(QueryMemSize))
+ return false;
+
for (auto &Val : SupportedValues) {
if (Val.ValTy != Query.Types[0])
continue;
if (Val.PtrTy != Query.Types[1])
continue;
- if (Val.MemSize != Query.MMODescrs[0].SizeInBits)
- continue;
- if (Val.MustBeNaturallyAligned &&
- Query.MMODescrs[0].SizeInBits % Query.MMODescrs[0].AlignInBits != 0)
+ if (Val.MemSize != QueryMemSize)
continue;
+ if (!Val.SystemSupportsUnalignedAccess &&
+ isUnalignedMemmoryAccess(QueryMemSize, Query.MMODescrs[0].AlignInBits))
+ return false;
return true;
}
return false;
@@ -79,19 +95,27 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
.legalFor({s32})
.maxScalar(0, s32);
+ // MIPS32r6 does not have alignment restrictions for memory access.
+ // For MIPS32r5 and older memory access must be naturally-aligned i.e. aligned
+ // to at least a multiple of its own size. There is however a two instruction
+ // combination that performs 4 byte unaligned access (lwr/lwl and swl/swr)
+ // therefore 4 byte load and store are legal and will use NoAlignRequirements.
+ bool NoAlignRequirements = true;
+
getActionDefinitionsBuilder({G_LOAD, G_STORE})
.legalIf([=, &ST](const LegalityQuery &Query) {
- if (CheckTy0Ty1MemSizeAlign(Query, {{s32, p0, 8, ST.hasMips32r6()},
- {s32, p0, 16, ST.hasMips32r6()},
- {s32, p0, 32, ST.hasMips32r6()},
- {p0, p0, 32, ST.hasMips32r6()},
- {s64, p0, 64, ST.hasMips32r6()}}))
+ if (CheckTy0Ty1MemSizeAlign(
+ Query, {{s32, p0, 8, NoAlignRequirements},
+ {s32, p0, 16, ST.systemSupportsUnalignedAccess()},
+ {s32, p0, 32, NoAlignRequirements},
+ {p0, p0, 32, NoAlignRequirements},
+ {s64, p0, 64, ST.systemSupportsUnalignedAccess()}}))
return true;
- if (ST.hasMSA() &&
- CheckTy0Ty1MemSizeAlign(Query, {{v16s8, p0, 128, false},
- {v8s16, p0, 128, false},
- {v4s32, p0, 128, false},
- {v2s64, p0, 128, false}}))
+ if (ST.hasMSA() && CheckTy0Ty1MemSizeAlign(
+ Query, {{v16s8, p0, 128, NoAlignRequirements},
+ {v8s16, p0, 128, NoAlignRequirements},
+ {v4s32, p0, 128, NoAlignRequirements},
+ {v2s64, p0, 128, NoAlignRequirements}}))
return true;
return false;
})
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index 9f3c5d1853ad..404612621a72 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -150,6 +150,19 @@ static bool isFloatingPointOpcodeDef(unsigned Opc) {
}
}
+static bool isGprbTwoInstrUnalignedLoadOrStore(const MachineInstr *MI) {
+ if (MI->getOpcode() == TargetOpcode::G_LOAD ||
+ MI->getOpcode() == TargetOpcode::G_STORE) {
+ auto MMO = *MI->memoperands_begin();
+ const MipsSubtarget &STI =
+ static_cast<const MipsSubtarget &>(MI->getMF()->getSubtarget());
+ if (MMO->getSize() == 4 && (!STI.systemSupportsUnalignedAccess() &&
+ MMO->getSize() > MMO->getAlignment()))
+ return true;
+ }
+ return false;
+}
+
static bool isAmbiguous(unsigned Opc) {
switch (Opc) {
case TargetOpcode::G_LOAD:
@@ -261,6 +274,11 @@ bool MipsRegisterBankInfo::TypeInfoForMF::visit(
startVisit(MI);
AmbiguousRegDefUseContainer DefUseContainer(MI);
+ if (isGprbTwoInstrUnalignedLoadOrStore(MI)) {
+ setTypes(MI, Integer);
+ return true;
+ }
+
if (AmbiguousTy == InstType::Ambiguous &&
(MI->getOpcode() == TargetOpcode::G_MERGE_VALUES ||
MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES))
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned.mir
new file mode 100644
index 000000000000..5452d62ba9e1
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned.mir
@@ -0,0 +1,89 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align4 = common global float 0.000000e+00, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define float @load_float_align1() {
+ entry:
+ %0 = load float, float* @float_align1, align 1
+ ret float %0
+ }
+
+ define float @load_float_align4() {
+ entry:
+ %0 = load float, float* @float_align4, align 4
+ ret float %0
+ }
+
+ define i32 @load_i32_align8() {
+ entry:
+ %0 = load i32, i32* @i32_align8, align 8
+ ret i32 %0
+ }
+
+...
+---
+name: load_float_align1
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align1
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align1
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align1
+ ; MIPS32: [[DEF:%[0-9]+]]:gpr32 = IMPLICIT_DEF
+ ; MIPS32: [[LWL:%[0-9]+]]:gpr32 = LWL [[ADDiu]], 3, [[DEF]] :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32: [[LWR:%[0-9]+]]:gpr32 = LWR [[ADDiu]], 0, [[LWL]] :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32: $f0 = COPY [[LWR]]
+ ; MIPS32: RetRA implicit $f0
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ %0:gprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align4
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align4
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align4
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align4
+ ; MIPS32: [[LWC1_:%[0-9]+]]:fgr32 = LWC1 [[ADDiu]], 0 :: (dereferenceable load 4 from @float_align4)
+ ; MIPS32: $f0 = COPY [[LWC1_]]
+ ; MIPS32: RetRA implicit $f0
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ %0:fprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align4)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_i32_align8
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align8
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @i32_align8
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @i32_align8
+ ; MIPS32: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu]], 0 :: (dereferenceable load 4 from @i32_align8, align 8)
+ ; MIPS32: $v0 = COPY [[LW]]
+ ; MIPS32: RetRA implicit $v0
+ %1:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ %0:gprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned_r6.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned_r6.mir
new file mode 100644
index 000000000000..b0ec86c4219b
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/load_4_unaligned_r6.mir
@@ -0,0 +1,90 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align8 = common global float 0.000000e+00, align 8
+ @i32_align2 = common global i32 0, align 2
+
+ define float @load_float_align1() {
+ entry:
+ %0 = load float, float* @float_align1, align 1
+ ret float %0
+ }
+
+ define float @load_float_align8() {
+ entry:
+ %0 = load float, float* @float_align8, align 8
+ ret float %0
+ }
+
+ define i32 @load_i32_align2() {
+ entry:
+ %0 = load i32, i32* @i32_align2, align 2
+ ret i32 %0
+ }
+
+...
+---
+name: load_float_align1
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+
+ ; MIPS32R6-LABEL: name: load_float_align1
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align1
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align1
+ ; MIPS32R6: [[LWC1_:%[0-9]+]]:fgr32 = LWC1 [[ADDiu]], 0 :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32R6: $f0 = COPY [[LWC1_]]
+ ; MIPS32R6: RetRA implicit $f0
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ %0:fprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align8
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+
+ ; MIPS32R6-LABEL: name: load_float_align8
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align8
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align8
+ ; MIPS32R6: [[LWC1_:%[0-9]+]]:fgr32 = LWC1 [[ADDiu]], 0 :: (dereferenceable load 4 from @float_align8, align 8)
+ ; MIPS32R6: $f0 = COPY [[LWC1_]]
+ ; MIPS32R6: RetRA implicit $f0
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align8
+ %0:fprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align8, align 8)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_i32_align2
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+
+ ; MIPS32R6-LABEL: name: load_i32_align2
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @i32_align2
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @i32_align2
+ ; MIPS32R6: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu]], 0 :: (dereferenceable load 4 from @i32_align2, align 2)
+ ; MIPS32R6: $v0 = COPY [[LW]]
+ ; MIPS32R6: RetRA implicit $v0
+ %1:gprb(p0) = G_GLOBAL_VALUE @i32_align2
+ %0:gprb(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align2, align 2)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned.mir
new file mode 100644
index 000000000000..2406393a6b3a
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned.mir
@@ -0,0 +1,99 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align4 = common global float 0.000000e+00, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define void @store_float_align1(float %a) {
+ entry:
+ store float %a, float* @float_align1, align 1
+ ret void
+ }
+
+ define void @store_float_align4(float %a) {
+ entry:
+ store float %a, float* @float_align4, align 4
+ ret void
+ }
+
+ define void @store_i32_align8(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align8, align 8
+ ret void
+ }
+
+...
+---
+name: store_float_align1
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align1
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align1
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align1
+ ; MIPS32: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]]
+ ; MIPS32: SWL [[COPY1]], [[ADDiu]], 3 :: (store 4 into @float_align1, align 1)
+ ; MIPS32: SWR [[COPY1]], [[ADDiu]], 0 :: (store 4 into @float_align1, align 1)
+ ; MIPS32: RetRA
+ %0:fprb(s32) = COPY $f12
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ %2:gprb(s32) = COPY %0(s32)
+ G_STORE %2(s32), %1(p0) :: (store 4 into @float_align1, align 1)
+ RetRA
+
+...
+---
+name: store_float_align4
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align4
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align4
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align4
+ ; MIPS32: SWC1 [[COPY]], [[ADDiu]], 0 :: (store 4 into @float_align4)
+ ; MIPS32: RetRA
+ %0:fprb(s32) = COPY $f12
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align4)
+ RetRA
+
+...
+---
+name: store_i32_align8
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align8
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @i32_align8
+ ; MIPS32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @i32_align8
+ ; MIPS32: SW [[COPY]], [[ADDiu]], 0 :: (store 4 into @i32_align8, align 8)
+ ; MIPS32: RetRA
+ %0:gprb(s32) = COPY $a0
+ %1:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align8, align 8)
+ RetRA
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned_r6.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned_r6.mir
new file mode 100644
index 000000000000..79228007fee1
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/store_4_unaligned_r6.mir
@@ -0,0 +1,96 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align8 = common global float 0.000000e+00, align 8
+ @i32_align2 = common global i32 0, align 2
+
+ define void @store_float_align1(float %a) #0 {
+ entry:
+ store float %a, float* @float_align1, align 1
+ ret void
+ }
+
+ define void @store_float_align8(float %a) #0 {
+ entry:
+ store float %a, float* @float_align8, align 8
+ ret void
+ }
+
+ define void @store_i32_align2(i32 signext %a) #0 {
+ entry:
+ store i32 %a, i32* @i32_align2, align 2
+ ret void
+ }
+
+...
+---
+name: store_float_align1
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32R6-LABEL: name: store_float_align1
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align1
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align1
+ ; MIPS32R6: SWC1 [[COPY]], [[ADDiu]], 0 :: (store 4 into @float_align1, align 1)
+ ; MIPS32R6: RetRA
+ %0:fprb(s32) = COPY $f12
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align1, align 1)
+ RetRA
+
+...
+---
+name: store_float_align8
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32R6-LABEL: name: store_float_align8
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:fgr32 = COPY $f12
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @float_align8
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @float_align8
+ ; MIPS32R6: SWC1 [[COPY]], [[ADDiu]], 0 :: (store 4 into @float_align8, align 8)
+ ; MIPS32R6: RetRA
+ %0:fprb(s32) = COPY $f12
+ %1:gprb(p0) = G_GLOBAL_VALUE @float_align8
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align8, align 8)
+ RetRA
+
+...
+---
+name: store_i32_align2
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32R6-LABEL: name: store_i32_align2
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32R6: [[LUi:%[0-9]+]]:gpr32 = LUi target-flags(mips-abs-hi) @i32_align2
+ ; MIPS32R6: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu [[LUi]], target-flags(mips-abs-lo) @i32_align2
+ ; MIPS32R6: SW [[COPY]], [[ADDiu]], 0 :: (store 4 into @i32_align2, align 2)
+ ; MIPS32R6: RetRA
+ %0:gprb(s32) = COPY $a0
+ %1:gprb(p0) = G_GLOBAL_VALUE @i32_align2
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align2, align 2)
+ RetRA
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/load_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/load_4_unaligned.mir
new file mode 100644
index 000000000000..e6e46e7e1af2
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/load_4_unaligned.mir
@@ -0,0 +1,239 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align2 = common global float 0.000000e+00, align 2
+ @float_align4 = common global float 0.000000e+00, align 4
+ @float_align8 = common global float 0.000000e+00, align 8
+ @i32_align1 = common global i32 0, align 1
+ @i32_align2 = common global i32 0, align 2
+ @i32_align4 = common global i32 0, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define float @load_float_align1() {
+ entry:
+ %0 = load float, float* @float_align1, align 1
+ ret float %0
+ }
+
+ define float @load_float_align2() {
+ entry:
+ %0 = load float, float* @float_align2, align 2
+ ret float %0
+ }
+
+ define float @load_float_align4() {
+ entry:
+ %0 = load float, float* @float_align4, align 4
+ ret float %0
+ }
+
+ define float @load_float_align8() {
+ entry:
+ %0 = load float, float* @float_align8, align 8
+ ret float %0
+ }
+
+ define i32 @load_i32_align1() {
+ entry:
+ %0 = load i32, i32* @i32_align1, align 1
+ ret i32 %0
+ }
+
+ define i32 @load_i32_align2() {
+ entry:
+ %0 = load i32, i32* @i32_align2, align 2
+ ret i32 %0
+ }
+
+ define i32 @load_i32_align4() {
+ entry:
+ %0 = load i32, i32* @i32_align4, align 4
+ ret i32 %0
+ }
+
+ define i32 @load_i32_align8() {
+ entry:
+ %0 = load i32, i32* @i32_align8, align 8
+ ret i32 %0
+ }
+
+...
+---
+name: load_float_align1
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align1
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align1
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align1
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align2
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align2
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align2
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align2, align 2)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align2
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align2
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align2, align 2)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align2
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align2, align 2)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align4
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align4
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align4)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align4
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align4)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align4
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align4)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align8
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align8
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align8
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align8, align 8)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align8
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align8
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align8, align 8)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align8
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align8, align 8)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_i32_align1
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align1
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align1
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align1, align 1)
+ ; MIPS32: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $v0
+ ; MIPS32R6-LABEL: name: load_i32_align1
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align1
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align1, align 1)
+ ; MIPS32R6: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $v0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align1
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align1, align 1)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
+---
+name: load_i32_align2
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align2
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align2
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align2, align 2)
+ ; MIPS32: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $v0
+ ; MIPS32R6-LABEL: name: load_i32_align2
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align2
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align2, align 2)
+ ; MIPS32R6: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $v0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align2
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align2, align 2)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
+---
+name: load_i32_align4
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align4
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align4
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align4)
+ ; MIPS32: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $v0
+ ; MIPS32R6-LABEL: name: load_i32_align4
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align4
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align4)
+ ; MIPS32R6: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $v0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align4
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align4)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
+---
+name: load_i32_align8
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align8
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ ; MIPS32: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $v0
+ ; MIPS32R6-LABEL: name: load_i32_align8
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ ; MIPS32R6: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $v0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align8
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/store_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/store_4_unaligned.mir
new file mode 100644
index 000000000000..ad6eaf4ed958
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/store_4_unaligned.mir
@@ -0,0 +1,271 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align2 = common global float 0.000000e+00, align 2
+ @float_align4 = common global float 0.000000e+00, align 4
+ @float_align8 = common global float 0.000000e+00, align 8
+ @i32_align1 = common global i32 0, align 1
+ @i32_align2 = common global i32 0, align 2
+ @i32_align4 = common global i32 0, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define void @store_float_align1(float %a) {
+ entry:
+ store float %a, float* @float_align1, align 1
+ ret void
+ }
+
+ define void @store_float_align2(float %a) {
+ entry:
+ store float %a, float* @float_align2, align 2
+ ret void
+ }
+
+ define void @store_float_align4(float %a) {
+ entry:
+ store float %a, float* @float_align4, align 4
+ ret void
+ }
+
+ define void @store_float_align8(float %a) {
+ entry:
+ store float %a, float* @float_align8, align 8
+ ret void
+ }
+
+ define void @store_i32_align1(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align1, align 1
+ ret void
+ }
+
+ define void @store_i32_align2(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align2, align 2
+ ret void
+ }
+
+ define void @store_i32_align4(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align4, align 4
+ ret void
+ }
+
+ define void @store_i32_align8(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align8, align 8
+ ret void
+ }
+
+...
+---
+name: store_float_align1
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align1
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align1, align 1)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align1
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align1, align 1)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align1
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align1, align 1)
+ RetRA
+
+...
+---
+name: store_float_align2
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align2
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align2
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align2, align 2)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align2
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align2
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align2, align 2)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align2
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align2, align 2)
+ RetRA
+
+...
+---
+name: store_float_align4
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align4
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align4)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align4
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align4)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align4
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align4)
+ RetRA
+
+...
+---
+name: store_float_align8
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align8
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align8
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align8, align 8)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align8
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @float_align8
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align8, align 8)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align8
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align8, align 8)
+ RetRA
+
+...
+---
+name: store_i32_align1
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align1
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align1
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align1, align 1)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_i32_align1
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align1
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align1, align 1)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $a0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align1
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align1, align 1)
+ RetRA
+
+...
+---
+name: store_i32_align2
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align2
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align2
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align2, align 2)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_i32_align2
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align2
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align2, align 2)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $a0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align2
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align2, align 2)
+ RetRA
+
+...
+---
+name: store_i32_align4
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align4
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align4
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align4)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_i32_align4
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align4
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align4)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $a0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align4
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align4)
+ RetRA
+
+...
+---
+name: store_i32_align8
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align8
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align8, align 8)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_i32_align8
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32R6: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align8, align 8)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $a0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align8
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align8, align 8)
+ RetRA
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_4_unaligned.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_4_unaligned.ll
new file mode 100644
index 000000000000..318407d619f5
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_4_unaligned.ll
@@ -0,0 +1,182 @@
+; 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
+
+ at float_align1 = common global float 0.000000e+00, align 1
+ at float_align2 = common global float 0.000000e+00, align 2
+ at float_align4 = common global float 0.000000e+00, align 4
+ at float_align8 = common global float 0.000000e+00, align 8
+ at i32_align1 = common global i32 0, align 1
+ at i32_align2 = common global i32 0, align 2
+ at i32_align4 = common global i32 0, align 4
+ at i32_align8 = common global i32 0, align 8
+
+define float @load_float_align1() {
+; MIPS32-LABEL: load_float_align1:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align1)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align1)
+; MIPS32-NEXT: # implicit-def: $v0
+; MIPS32-NEXT: lwl $2, 3($1)
+; MIPS32-NEXT: lwr $2, 0($1)
+; MIPS32-NEXT: mtc1 $2, $f0
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_float_align1:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align1)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align1)
+; MIPS32R6-NEXT: lwc1 $f0, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load float, float* @float_align1, align 1
+ ret float %0
+}
+
+define float @load_float_align2() {
+; MIPS32-LABEL: load_float_align2:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align2)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align2)
+; MIPS32-NEXT: # implicit-def: $v0
+; MIPS32-NEXT: lwl $2, 3($1)
+; MIPS32-NEXT: lwr $2, 0($1)
+; MIPS32-NEXT: mtc1 $2, $f0
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_float_align2:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align2)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align2)
+; MIPS32R6-NEXT: lwc1 $f0, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load float, float* @float_align2, align 2
+ ret float %0
+}
+
+define float @load_float_align4() {
+; MIPS32-LABEL: load_float_align4:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align4)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align4)
+; MIPS32-NEXT: lwc1 $f0, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_float_align4:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align4)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align4)
+; MIPS32R6-NEXT: lwc1 $f0, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load float, float* @float_align4, align 4
+ ret float %0
+}
+
+define float @load_float_align8() {
+; MIPS32-LABEL: load_float_align8:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align8)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align8)
+; MIPS32-NEXT: lwc1 $f0, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_float_align8:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align8)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align8)
+; MIPS32R6-NEXT: lwc1 $f0, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load float, float* @float_align8, align 8
+ ret float %0
+}
+
+define i32 @load_i32_align1() {
+; MIPS32-LABEL: load_i32_align1:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align1)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align1)
+; MIPS32-NEXT: # implicit-def: $v0
+; MIPS32-NEXT: lwl $2, 3($1)
+; MIPS32-NEXT: lwr $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_i32_align1:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align1)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align1)
+; MIPS32R6-NEXT: lw $2, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load i32, i32* @i32_align1, align 1
+ ret i32 %0
+}
+
+define i32 @load_i32_align2() {
+; MIPS32-LABEL: load_i32_align2:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align2)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align2)
+; MIPS32-NEXT: # implicit-def: $v0
+; MIPS32-NEXT: lwl $2, 3($1)
+; MIPS32-NEXT: lwr $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_i32_align2:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align2)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align2)
+; MIPS32R6-NEXT: lw $2, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load i32, i32* @i32_align2, align 2
+ ret i32 %0
+}
+
+define i32 @load_i32_align4() {
+; MIPS32-LABEL: load_i32_align4:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align4)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align4)
+; MIPS32-NEXT: lw $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_i32_align4:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align4)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align4)
+; MIPS32R6-NEXT: lw $2, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load i32, i32* @i32_align4, align 4
+ ret i32 %0
+}
+
+define i32 @load_i32_align8() {
+; MIPS32-LABEL: load_i32_align8:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align8)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align8)
+; MIPS32-NEXT: lw $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: load_i32_align8:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align8)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align8)
+; MIPS32R6-NEXT: lw $2, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ %0 = load i32, i32* @i32_align8, align 8
+ ret i32 %0
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
index a48eda23e9f1..410c53f98751 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
@@ -249,8 +249,8 @@ define void @phi_ambiguous_i64_in_fpr(i1 %cnd, i64* %i64_ptr_a, i64* %i64_ptr_b,
; MIPS32-NEXT: jr $ra
; MIPS32-NEXT: nop
entry:
- %0 = load i64, i64* %i64_ptr_a, align 4
- %1 = load i64, i64* %i64_ptr_b, align 4
+ %0 = load i64, i64* %i64_ptr_a, align 8
+ %1 = load i64, i64* %i64_ptr_b, align 8
br i1 %cnd, label %cond.true, label %cond.false
cond.true:
@@ -261,7 +261,7 @@ cond.false:
cond.end:
%cond = phi i64 [ %0, %cond.true ], [ %1, %cond.false ]
- store i64 %cond, i64* %i64_ptr_c, align 4
+ store i64 %cond, i64* %i64_ptr_c, align 8
ret void
}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/store_4_unaligned.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/store_4_unaligned.ll
new file mode 100644
index 000000000000..37c40392e7a0
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/store_4_unaligned.ll
@@ -0,0 +1,178 @@
+; 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
+
+ at float_align1 = common global float 0.000000e+00, align 1
+ at float_align2 = common global float 0.000000e+00, align 2
+ at float_align4 = common global float 0.000000e+00, align 4
+ at float_align8 = common global float 0.000000e+00, align 8
+ at i32_align1 = common global i32 0, align 1
+ at i32_align2 = common global i32 0, align 2
+ at i32_align4 = common global i32 0, align 4
+ at i32_align8 = common global i32 0, align 8
+
+define void @store_float_align1(float %a) {
+; MIPS32-LABEL: store_float_align1:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align1)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align1)
+; MIPS32-NEXT: mfc1 $2, $f12
+; MIPS32-NEXT: swl $2, 3($1)
+; MIPS32-NEXT: swr $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_float_align1:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align1)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align1)
+; MIPS32R6-NEXT: swc1 $f12, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store float %a, float* @float_align1, align 1
+ ret void
+}
+
+define void @store_float_align2(float %a) {
+; MIPS32-LABEL: store_float_align2:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align2)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align2)
+; MIPS32-NEXT: mfc1 $2, $f12
+; MIPS32-NEXT: swl $2, 3($1)
+; MIPS32-NEXT: swr $2, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_float_align2:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align2)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align2)
+; MIPS32R6-NEXT: swc1 $f12, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store float %a, float* @float_align2, align 2
+ ret void
+}
+
+define void @store_float_align4(float %a) {
+; MIPS32-LABEL: store_float_align4:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align4)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align4)
+; MIPS32-NEXT: swc1 $f12, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_float_align4:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align4)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align4)
+; MIPS32R6-NEXT: swc1 $f12, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store float %a, float* @float_align4, align 4
+ ret void
+}
+
+define void @store_float_align8(float %a) {
+; MIPS32-LABEL: store_float_align8:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(float_align8)
+; MIPS32-NEXT: addiu $1, $1, %lo(float_align8)
+; MIPS32-NEXT: swc1 $f12, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_float_align8:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(float_align8)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(float_align8)
+; MIPS32R6-NEXT: swc1 $f12, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store float %a, float* @float_align8, align 8
+ ret void
+}
+
+define void @store_i32_align1(i32 signext %a) {
+; MIPS32-LABEL: store_i32_align1:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align1)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align1)
+; MIPS32-NEXT: swl $4, 3($1)
+; MIPS32-NEXT: swr $4, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_i32_align1:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align1)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align1)
+; MIPS32R6-NEXT: sw $4, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store i32 %a, i32* @i32_align1, align 1
+ ret void
+}
+
+define void @store_i32_align2(i32 signext %a) {
+; MIPS32-LABEL: store_i32_align2:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align2)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align2)
+; MIPS32-NEXT: swl $4, 3($1)
+; MIPS32-NEXT: swr $4, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_i32_align2:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align2)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align2)
+; MIPS32R6-NEXT: sw $4, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store i32 %a, i32* @i32_align2, align 2
+ ret void
+}
+
+define void @store_i32_align4(i32 signext %a) {
+; MIPS32-LABEL: store_i32_align4:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align4)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align4)
+; MIPS32-NEXT: sw $4, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_i32_align4:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align4)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align4)
+; MIPS32R6-NEXT: sw $4, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store i32 %a, i32* @i32_align4, align 4
+ ret void
+}
+
+define void @store_i32_align8(i32 signext %a) {
+; MIPS32-LABEL: store_i32_align8:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: lui $1, %hi(i32_align8)
+; MIPS32-NEXT: addiu $1, $1, %lo(i32_align8)
+; MIPS32-NEXT: sw $4, 0($1)
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+;
+; MIPS32R6-LABEL: store_i32_align8:
+; MIPS32R6: # %bb.0: # %entry
+; MIPS32R6-NEXT: lui $1, %hi(i32_align8)
+; MIPS32R6-NEXT: addiu $1, $1, %lo(i32_align8)
+; MIPS32R6-NEXT: sw $4, 0($1)
+; MIPS32R6-NEXT: jrc $ra
+entry:
+ store i32 %a, i32* @i32_align8, align 8
+ ret void
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/load_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/load_4_unaligned.mir
new file mode 100644
index 000000000000..a1eeca392ba1
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/load_4_unaligned.mir
@@ -0,0 +1,97 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align4 = common global float 0.000000e+00, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define float @load_float_align1() {
+ entry:
+ %0 = load float, float* @float_align1, align 1
+ ret float %0
+ }
+
+ define float @load_float_align4() {
+ entry:
+ %0 = load float, float* @float_align4, align 4
+ ret float %0
+ }
+
+ define i32 @load_i32_align8() {
+ entry:
+ %0 = load i32, i32* @i32_align8, align 8
+ ret i32 %0
+ }
+
+...
+---
+name: load_float_align1
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align1
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align1
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:fprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align1
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align1, align 1)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_float_align4
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_float_align4
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32: [[LOAD:%[0-9]+]]:fprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align4)
+ ; MIPS32: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $f0
+ ; MIPS32R6-LABEL: name: load_float_align4
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:fprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @float_align4)
+ ; MIPS32R6: $f0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $f0
+ %1:_(p0) = G_GLOBAL_VALUE @float_align4
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @float_align4)
+ $f0 = COPY %0(s32)
+ RetRA implicit $f0
+
+...
+---
+name: load_i32_align8
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ ; MIPS32-LABEL: name: load_i32_align8
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ ; MIPS32: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32: RetRA implicit $v0
+ ; MIPS32R6-LABEL: name: load_i32_align8
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32R6: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[GV]](p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ ; MIPS32R6: $v0 = COPY [[LOAD]](s32)
+ ; MIPS32R6: RetRA implicit $v0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align8
+ %0:_(s32) = G_LOAD %1(p0) :: (dereferenceable load 4 from @i32_align8, align 8)
+ $v0 = COPY %0(s32)
+ RetRA implicit $v0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
index 09d26f0b563d..26fc6d1d0184 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir
@@ -34,8 +34,8 @@
define void @phi_ambiguous_i64_in_fpr(i1 %cnd, i64* %i64_ptr_a, i64* %i64_ptr_b, i64* %i64_ptr_c) {
entry:
- %0 = load i64, i64* %i64_ptr_a, align 4
- %1 = load i64, i64* %i64_ptr_b, align 4
+ %0 = load i64, i64* %i64_ptr_a, align 8
+ %1 = load i64, i64* %i64_ptr_b, align 8
br i1 %cnd, label %cond.true, label %cond.false
cond.true: ; preds = %entry
@@ -46,7 +46,7 @@
cond.end: ; preds = %cond.false, %cond.true
%cond = phi i64 [ %0, %cond.true ], [ %1, %cond.false ]
- store i64 %cond, i64* %i64_ptr_c, align 4
+ store i64 %cond, i64* %i64_ptr_c, align 8
ret void
}
@@ -230,8 +230,8 @@ body: |
; MIPS32: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
; MIPS32: [[COPY2:%[0-9]+]]:gprb(p0) = COPY $a2
; MIPS32: [[COPY3:%[0-9]+]]:gprb(p0) = COPY $a3
- ; MIPS32: [[LOAD:%[0-9]+]]:fprb(s64) = G_LOAD [[COPY1]](p0) :: (load 8 from %ir.i64_ptr_a, align 4)
- ; MIPS32: [[LOAD1:%[0-9]+]]:fprb(s64) = G_LOAD [[COPY2]](p0) :: (load 8 from %ir.i64_ptr_b, align 4)
+ ; MIPS32: [[LOAD:%[0-9]+]]:fprb(s64) = G_LOAD [[COPY1]](p0) :: (load 8 from %ir.i64_ptr_a)
+ ; MIPS32: [[LOAD1:%[0-9]+]]:fprb(s64) = G_LOAD [[COPY2]](p0) :: (load 8 from %ir.i64_ptr_b)
; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
; MIPS32: [[COPY4:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY4]], [[C]]
@@ -244,7 +244,7 @@ body: |
; MIPS32: successors: %bb.3(0x80000000)
; MIPS32: bb.3.cond.end:
; MIPS32: [[PHI:%[0-9]+]]:fprb(s64) = G_PHI [[LOAD]](s64), %bb.1, [[LOAD1]](s64), %bb.2
- ; MIPS32: G_STORE [[PHI]](s64), [[COPY3]](p0) :: (store 8 into %ir.i64_ptr_c, align 4)
+ ; MIPS32: G_STORE [[PHI]](s64), [[COPY3]](p0) :: (store 8 into %ir.i64_ptr_c)
; MIPS32: RetRA
bb.1.entry:
liveins: $a0, $a1, $a2, $a3
@@ -253,8 +253,8 @@ body: |
%1:_(p0) = COPY $a1
%2:_(p0) = COPY $a2
%3:_(p0) = COPY $a3
- %5:_(s64) = G_LOAD %1(p0) :: (load 8 from %ir.i64_ptr_a, align 4)
- %6:_(s64) = G_LOAD %2(p0) :: (load 8 from %ir.i64_ptr_b, align 4)
+ %5:_(s64) = G_LOAD %1(p0) :: (load 8 from %ir.i64_ptr_a)
+ %6:_(s64) = G_LOAD %2(p0) :: (load 8 from %ir.i64_ptr_b)
%9:_(s32) = G_CONSTANT i32 1
%10:_(s32) = COPY %4(s32)
%8:_(s32) = G_AND %10, %9
@@ -268,7 +268,7 @@ body: |
bb.4.cond.end:
%7:_(s64) = G_PHI %5(s64), %bb.2, %6(s64), %bb.3
- G_STORE %7(s64), %3(p0) :: (store 8 into %ir.i64_ptr_c, align 4)
+ G_STORE %7(s64), %3(p0) :: (store 8 into %ir.i64_ptr_c)
RetRA
...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/store_4_unaligned.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/store_4_unaligned.mir
new file mode 100644
index 000000000000..de20ea20d032
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/store_4_unaligned.mir
@@ -0,0 +1,110 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -mcpu=mips32r6 -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32R6
+--- |
+
+ @float_align1 = common global float 0.000000e+00, align 1
+ @float_align4 = common global float 0.000000e+00, align 4
+ @i32_align8 = common global i32 0, align 8
+
+ define void @store_float_align1(float %a) {
+ entry:
+ store float %a, float* @float_align1, align 1
+ ret void
+ }
+
+ define void @store_float_align4(float %a) {
+ entry:
+ store float %a, float* @float_align4, align 4
+ ret void
+ }
+
+ define void @store_i32_align8(i32 signext %a) {
+ entry:
+ store i32 %a, i32* @i32_align8, align 8
+ ret void
+ }
+
+...
+---
+name: store_float_align1
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align1
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:fprb(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
+ ; MIPS32: G_STORE [[COPY1]](s32), [[GV]](p0) :: (store 4 into @float_align1, align 1)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align1
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:fprb(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align1
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align1, align 1)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align1
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align1, align 1)
+ RetRA
+
+...
+---
+name: store_float_align4
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $f12
+
+ ; MIPS32-LABEL: name: store_float_align4
+ ; MIPS32: liveins: $f12
+ ; MIPS32: [[COPY:%[0-9]+]]:fprb(s32) = COPY $f12
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align4)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_float_align4
+ ; MIPS32R6: liveins: $f12
+ ; MIPS32R6: [[COPY:%[0-9]+]]:fprb(s32) = COPY $f12
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @float_align4
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @float_align4)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $f12
+ %1:_(p0) = G_GLOBAL_VALUE @float_align4
+ G_STORE %0(s32), %1(p0) :: (store 4 into @float_align4)
+ RetRA
+
+...
+---
+name: store_i32_align8
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0
+
+ ; MIPS32-LABEL: name: store_i32_align8
+ ; MIPS32: liveins: $a0
+ ; MIPS32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+ ; MIPS32: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align8, align 8)
+ ; MIPS32: RetRA
+ ; MIPS32R6-LABEL: name: store_i32_align8
+ ; MIPS32R6: liveins: $a0
+ ; MIPS32R6: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+ ; MIPS32R6: [[GV:%[0-9]+]]:gprb(p0) = G_GLOBAL_VALUE @i32_align8
+ ; MIPS32R6: G_STORE [[COPY]](s32), [[GV]](p0) :: (store 4 into @i32_align8, align 8)
+ ; MIPS32R6: RetRA
+ %0:_(s32) = COPY $a0
+ %1:_(p0) = G_GLOBAL_VALUE @i32_align8
+ G_STORE %0(s32), %1(p0) :: (store 4 into @i32_align8, align 8)
+ RetRA
+
+...
More information about the llvm-commits
mailing list