[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