[llvm] e34e809 - [Mips][GlobalISel] Fix Big Endian lowering (#225972)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 03:05:21 PDT 2026
Author: Jiaxun Yang
Date: 2026-09-24T11:05:11+01:00
New Revision: e34e80918571ac5af5d00191bc053d7d60c1f039
URL: https://github.com/llvm/llvm-project/commit/e34e80918571ac5af5d00191bc053d7d60c1f039
DIFF: https://github.com/llvm/llvm-project/commit/e34e80918571ac5af5d00191bc053d7d60c1f039.diff
LOG: [Mips][GlobalISel] Fix Big Endian lowering (#225972)
Flip on the big-endian switch in Mips call lowering. Fix split memory
piece placement, short-load bit extraction, and unaligned left/right
instruction offsets for big-endian targets.
Add BE/LE test coverage.
Added:
llvm/test/CodeGen/Mips/GlobalISel/irtranslator/big-endian.ll
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/big-endian-memory.ll
Modified:
llvm/lib/Target/Mips/MipsCallLowering.h
llvm/lib/Target/Mips/MipsInstructionSelector.cpp
llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
llvm/test/CodeGen/Mips/GlobalISel/irtranslator/extend_args.ll
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_constants.ll
llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_store_vec.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h
index 9f114d55db4c6..871cc99aad85d 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.h
+++ b/llvm/lib/Target/Mips/MipsCallLowering.h
@@ -24,6 +24,8 @@ class MipsCallLowering : public CallLowering {
public:
MipsCallLowering(const MipsTargetLowering &TLI);
+ bool enableBigEndian() const override { return true; }
+
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
ArrayRef<Register> VRegs,
FunctionLoweringInfo &FLI) const override;
diff --git a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
index 2099df11f5b53..e84e7b3a24580 100644
--- a/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
+++ b/llvm/lib/Target/Mips/MipsInstructionSelector.cpp
@@ -457,10 +457,12 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
if (MMO->getSize() != 4 || !isRegInGprb(I.getOperand(0).getReg(), MRI))
return false;
+ unsigned LeftOffset = SignedOffset + (STI.isLittle() ? 3 : 0);
+ unsigned RightOffset = SignedOffset + (STI.isLittle() ? 0 : 3);
if (I.getOpcode() == G_STORE) {
- if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, SignedOffset + 3, MMO))
+ if (!buildUnalignedStore(I, Mips::SWL, BaseAddr, LeftOffset, MMO))
return false;
- if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, SignedOffset, MMO))
+ if (!buildUnalignedStore(I, Mips::SWR, BaseAddr, RightOffset, MMO))
return false;
I.eraseFromParent();
return true;
@@ -471,11 +473,11 @@ bool MipsInstructionSelector::select(MachineInstr &I) {
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,
+ if (!buildUnalignedLoad(I, Mips::LWL, Tmp, BaseAddr, LeftOffset,
ImplDef, MMO))
return false;
if (!buildUnalignedLoad(I, Mips::LWR, I.getOperand(0).getReg(),
- BaseAddr, SignedOffset, Tmp, MMO))
+ BaseAddr, RightOffset, Tmp, MMO))
return false;
I.eraseFromParent();
return true;
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index b697ca827daa8..645bb6708ec3d 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -370,9 +370,13 @@ bool MipsLegalizerInfo::legalizeCustom(
Register BaseAddr = MI.getOperand(1).getReg();
LLT PtrTy = MRI.getType(BaseAddr);
MachineFunction &MF = MIRBuilder.getMF();
+ bool IsLittle = MF.getDataLayout().isLittleEndian();
+ unsigned FirstMemSize = IsLittle ? P2HalfMemSize : RemMemSize;
- auto P2HalfMemOp = MF.getMachineMemOperand(MMOBase, 0, P2HalfMemSize);
- auto RemMemOp = MF.getMachineMemOperand(MMOBase, P2HalfMemSize, RemMemSize);
+ auto P2HalfMemOp = MF.getMachineMemOperand(
+ MMOBase, IsLittle ? 0 : RemMemSize, P2HalfMemSize);
+ auto RemMemOp = MF.getMachineMemOperand(
+ MMOBase, IsLittle ? P2HalfMemSize : 0, RemMemSize);
if (MI.getOpcode() == G_STORE) {
// Widen Val to s32 or s64 in order to create legal G_LSHR or G_UNMERGE.
@@ -381,18 +385,20 @@ bool MipsLegalizerInfo::legalizeCustom(
if (Size > 32 && Size < 64)
Val = MIRBuilder.buildAnyExt(s64, Val).getReg(0);
- auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
- auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
+ auto Offset = MIRBuilder.buildConstant(s32, FirstMemSize);
+ Register Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, Offset).getReg(0);
+ Register LoAddr = IsLittle ? BaseAddr : Addr;
+ Register HiAddr = IsLittle ? Addr : BaseAddr;
if (MI.getOpcode() == G_STORE && MemSize <= 4) {
- MIRBuilder.buildStore(Val, BaseAddr, *P2HalfMemOp);
+ MIRBuilder.buildStore(Val, LoAddr, *P2HalfMemOp);
auto C_P2Half_InBits = MIRBuilder.buildConstant(s32, P2HalfMemSize * 8);
auto Shift = MIRBuilder.buildLShr(s32, Val, C_P2Half_InBits);
- MIRBuilder.buildStore(Shift, Addr, *RemMemOp);
+ MIRBuilder.buildStore(Shift, HiAddr, *RemMemOp);
} else {
auto Unmerge = MIRBuilder.buildUnmerge(s32, Val);
- MIRBuilder.buildStore(Unmerge.getReg(0), BaseAddr, *P2HalfMemOp);
- MIRBuilder.buildStore(Unmerge.getReg(1), Addr, *RemMemOp);
+ MIRBuilder.buildStore(Unmerge.getReg(0), LoAddr, *P2HalfMemOp);
+ MIRBuilder.buildStore(Unmerge.getReg(1), HiAddr, *RemMemOp);
}
}
@@ -402,7 +408,12 @@ bool MipsLegalizerInfo::legalizeCustom(
// This is anyextending load, use 4 byte lwr/lwl.
auto *Load4MMO = MF.getMachineMemOperand(MMOBase, 0, 4);
- if (Size == 32)
+ if (!IsLittle) {
+ auto Load = MIRBuilder.buildLoad(s32, BaseAddr, *Load4MMO);
+ auto ShiftAmt = MIRBuilder.buildConstant(s32, (4 - MemSize) * 8);
+ auto Shift = MIRBuilder.buildLShr(s32, Load, ShiftAmt);
+ MIRBuilder.buildAnyExtOrTrunc(Val, Shift);
+ } else if (Size == 32)
MIRBuilder.buildLoad(Val, BaseAddr, *Load4MMO);
else {
auto Load = MIRBuilder.buildLoad(s32, BaseAddr, *Load4MMO);
@@ -410,11 +421,14 @@ bool MipsLegalizerInfo::legalizeCustom(
}
} else {
- auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
- auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
-
- auto Load_P2Half = MIRBuilder.buildLoad(s32, BaseAddr, *P2HalfMemOp);
- auto Load_Rem = MIRBuilder.buildLoad(s32, Addr, *RemMemOp);
+ auto Offset = MIRBuilder.buildConstant(s32, FirstMemSize);
+ Register Addr =
+ MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, Offset).getReg(0);
+ Register LoAddr = IsLittle ? BaseAddr : Addr;
+ Register HiAddr = IsLittle ? Addr : BaseAddr;
+
+ auto Load_P2Half = MIRBuilder.buildLoad(s32, LoAddr, *P2HalfMemOp);
+ auto Load_Rem = MIRBuilder.buildLoad(s32, HiAddr, *RemMemOp);
if (Size == 64)
MIRBuilder.buildMergeLikeInstr(Val, {Load_P2Half, Load_Rem});
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
index acf478b364436..205fbba4f50e3 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/aggregate_struct_return.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
define { float, float } @add_complex_float(ptr %a, ptr %b) {
; MIPS32-LABEL: name: add_complex_float
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/big-endian.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/big-endian.ll
new file mode 100644
index 0000000000000..97621f6e54ab5
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/big-endian.ll
@@ -0,0 +1,105 @@
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,BE,FP32
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,LE,FP32
+; RUN: llc -O0 -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+fp64 -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,BE,FP64
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r2 -mattr=+fp64 -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,LE,FP64
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - > /dev/null
+; RUN: llc -O0 -mtriple=mips-linux-gnu -mcpu=mips32r2 -mattr=+fp64 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - > /dev/null
+
+; Check high-word-first ABI assignments on BE.
+define i64 @integer_regs(i64 %x) {
+; CHECK-LABEL: name: integer_regs
+; BE: [[LO:%[0-9]+]]:_(s32) = COPY $a1
+; BE-NEXT: [[HI:%[0-9]+]]:_(s32) = COPY $a0
+; LE: [[LO:%[0-9]+]]:_(s32) = COPY $a0
+; LE-NEXT: [[HI:%[0-9]+]]:_(s32) = COPY $a1
+; CHECK-NEXT: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LO]](s32), [[HI]](s32)
+; CHECK-NEXT: [[RLO:%[0-9]+]]:_(s32), [[RHI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[X]](s64)
+; BE-NEXT: $v1 = COPY [[RLO]](s32)
+; BE-NEXT: $v0 = COPY [[RHI]](s32)
+; LE-NEXT: $v0 = COPY [[RLO]](s32)
+; LE-NEXT: $v1 = COPY [[RHI]](s32)
+ ret i64 %x
+}
+
+; A preceding i32 forces the i64 into the aligned a2/a3 register pair.
+declare i64 @callee_integer(i32, i64)
+define i64 @integer_call(i64 %x) {
+; CHECK-LABEL: name: integer_call
+; CHECK: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES
+; CHECK: [[LO:%[0-9]+]]:_(s32), [[HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[X]](s64)
+; CHECK: $a0 = COPY
+; BE-NEXT: $a3 = COPY [[LO]](s32)
+; BE-NEXT: $a2 = COPY [[HI]](s32)
+; LE-NEXT: $a2 = COPY [[LO]](s32)
+; LE-NEXT: $a3 = COPY [[HI]](s32)
+; CHECK-NEXT: JAL @callee_integer,
+; BE-NEXT: [[RLO:%[0-9]+]]:_(s32) = COPY $v1
+; BE-NEXT: [[RHI:%[0-9]+]]:_(s32) = COPY $v0
+; LE-NEXT: [[RLO:%[0-9]+]]:_(s32) = COPY $v0
+; LE-NEXT: [[RHI:%[0-9]+]]:_(s32) = COPY $v1
+; CHECK-NEXT: {{%[0-9]+}}:_(s64) = G_MERGE_VALUES [[RLO]](s32), [[RHI]](s32)
+ %r = call i64 @callee_integer(i32 1, i64 %x)
+ ret i64 %r
+}
+
+; Check high-word-first stack arguments on BE.
+define i64 @integer_stack(i32 %a, i32 %b, i32 %c, i32 %d, i64 %x) {
+; CHECK-LABEL: name: integer_stack
+; BE: id: 0, type: default, offset: 16, size: 4, alignment: 8,
+; BE: id: 1, type: default, offset: 20, size: 4, alignment: 4,
+; LE: id: 0, type: default, offset: 20, size: 4, alignment: 4,
+; LE: id: 1, type: default, offset: 16, size: 4, alignment: 8,
+; CHECK: [[LP:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+; CHECK-NEXT: [[LO:%[0-9]+]]:_(s32) = G_LOAD [[LP]](p0)
+; CHECK-NEXT: [[HP:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+; CHECK-NEXT: [[HI:%[0-9]+]]:_(s32) = G_LOAD [[HP]](p0)
+; CHECK-NEXT: {{%[0-9]+}}:_(s64) = G_MERGE_VALUES [[LO]](s32), [[HI]](s32)
+ ret i64 %x
+}
+
+declare void @callee_stack(i32, i32, i32, i32, i64)
+define void @integer_stack_call(i64 %x) {
+; CHECK-LABEL: name: integer_stack_call
+; CHECK: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES
+; CHECK: [[LO:%[0-9]+]]:_(s32), [[HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[X]](s64)
+; BE: G_STORE [[LO]](s32), {{.*}} :: (store (s32) into stack + 20)
+; BE: G_STORE [[HI]](s32), {{.*}} :: (store (s32) into stack + 16, align 8)
+; LE: G_STORE [[LO]](s32), {{.*}} :: (store (s32) into stack + 16, align 8)
+; LE: G_STORE [[HI]](s32), {{.*}} :: (store (s32) into stack + 20)
+; CHECK: JAL @callee_stack,
+ call void @callee_stack(i32 1, i32 2, i32 3, i32 4, i64 %x)
+ ret void
+}
+
+; Doubles passed in GPRs use the target's custom assignment handler.
+define double @double_regs(i32 %a, double %x) {
+; CHECK-LABEL: name: double_regs
+; CHECK: [[A2:%[0-9]+]]:_(s32) = COPY $a2
+; CHECK-NEXT: [[A3:%[0-9]+]]:_(s32) = COPY $a3
+; BE-NEXT: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A3]](s32), [[A2]](s32)
+; LE-NEXT: [[X:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[A2]](s32), [[A3]](s32)
+; FP32-NEXT: $d0 = COPY [[X]](s64)
+; FP64-NEXT: $d0_64 = COPY [[X]](s64)
+ ret double %x
+}
+
+declare double @callee_double(i32, double)
+define double @double_call(double %x) {
+; CHECK-LABEL: name: double_call
+; FP32: [[X:%[0-9]+]]:_(s64) = COPY $d6
+; FP64: [[X:%[0-9]+]]:_(s64) = COPY $d12_64
+; CHECK: [[LO:%[0-9]+]]:_(s32), [[HI:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[X]](s64)
+; CHECK: $a0 = COPY
+; BE-NEXT: $a2 = COPY [[HI]](s32)
+; BE-NEXT: $a3 = COPY [[LO]](s32)
+; LE-NEXT: $a2 = COPY [[LO]](s32)
+; LE-NEXT: $a3 = COPY [[HI]](s32)
+; CHECK-NEXT: JAL @callee_double,
+; FP32-NEXT: [[R:%[0-9]+]]:_(s64) = COPY $d0
+; FP64-NEXT: [[R:%[0-9]+]]:_(s64) = COPY $d0_64
+; CHECK-NEXT: ADJCALLSTACKUP
+; FP32-NEXT: $d0 = COPY [[R]](s64)
+; FP64-NEXT: $d0_64 = COPY [[R]](s64)
+ %r = call double @callee_double(i32 1, double %x)
+ ret double %r
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/extend_args.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/extend_args.ll
index b8b5c0cba9938..1eb5d8db69ded 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/extend_args.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/extend_args.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32
define signext i8 @sext_arg_i8(i8 signext %a) {
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/big-endian-memory.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/big-endian-memory.ll
new file mode 100644
index 0000000000000..ffc95be49a148
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/big-endian-memory.ll
@@ -0,0 +1,303 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=mips-linux-gnu -mcpu=mips32r2 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=BE
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r2 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=LE
+; RUN: llc -O0 -mtriple=mips-linux-gnu -mcpu=mips32r6 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=BE-R6
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r6 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=LE-R6
+
+define i32 @load_i16(ptr %p) {
+; BE-LABEL: load_i16:
+; BE: # %bb.0:
+; BE-NEXT: # implicit-def: $at
+; BE-NEXT: lwl $1, 0($4)
+; BE-NEXT: lwr $1, 3($4)
+; BE-NEXT: srl $2, $1, 16
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: load_i16:
+; LE: # %bb.0:
+; LE-NEXT: # implicit-def: $at
+; LE-NEXT: lwl $1, 3($4)
+; LE-NEXT: lwr $1, 0($4)
+; LE-NEXT: andi $2, $1, 65535
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: load_i16:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: lhu $2, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: load_i16:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: lhu $2, 0($4)
+; LE-R6-NEXT: jrc $ra
+ %v = load i16, ptr %p, align 1
+ %r = zext i16 %v to i32
+ ret i32 %r
+}
+
+define i32 @load_i24(ptr %p) {
+; BE-LABEL: load_i24:
+; BE: # %bb.0:
+; BE-NEXT: # implicit-def: $at
+; BE-NEXT: lwl $1, 0($4)
+; BE-NEXT: lwr $1, 3($4)
+; BE-NEXT: srl $1, $1, 8
+; BE-NEXT: sll $1, $1, 8
+; BE-NEXT: sra $2, $1, 8
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: load_i24:
+; LE: # %bb.0:
+; LE-NEXT: # implicit-def: $at
+; LE-NEXT: lwl $1, 3($4)
+; LE-NEXT: lwr $1, 0($4)
+; LE-NEXT: sll $1, $1, 8
+; LE-NEXT: sra $2, $1, 8
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: load_i24:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: lw $1, 0($4)
+; BE-R6-NEXT: srl $1, $1, 8
+; BE-R6-NEXT: sll $1, $1, 8
+; BE-R6-NEXT: sra $2, $1, 8
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: load_i24:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: lw $1, 0($4)
+; LE-R6-NEXT: sll $1, $1, 8
+; LE-R6-NEXT: sra $2, $1, 8
+; LE-R6-NEXT: jrc $ra
+ %v = load i24, ptr %p, align 1
+ %r = sext i24 %v to i32
+ ret i32 %r
+}
+
+define i64 @load_i40(ptr %p) {
+; BE-LABEL: load_i40:
+; BE: # %bb.0:
+; BE-NEXT: # implicit-def: $v0
+; BE-NEXT: lwl $2, 1($4)
+; BE-NEXT: lwr $2, 4($4)
+; BE-NEXT: lbu $1, 0($4)
+; BE-NEXT: addiu $3, $zero, 65535
+; BE-NEXT: and $3, $2, $3
+; BE-NEXT: andi $2, $1, 255
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: load_i40:
+; LE: # %bb.0:
+; LE-NEXT: # implicit-def: $v0
+; LE-NEXT: lwl $2, 3($4)
+; LE-NEXT: lwr $2, 0($4)
+; LE-NEXT: lbu $1, 4($4)
+; LE-NEXT: addiu $3, $zero, 65535
+; LE-NEXT: and $2, $2, $3
+; LE-NEXT: andi $3, $1, 255
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: load_i40:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: lw $2, 1($4)
+; BE-R6-NEXT: lbu $1, 0($4)
+; BE-R6-NEXT: addiu $3, $zero, 65535
+; BE-R6-NEXT: and $3, $2, $3
+; BE-R6-NEXT: andi $2, $1, 255
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: load_i40:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: lw $2, 0($4)
+; LE-R6-NEXT: lbu $1, 4($4)
+; LE-R6-NEXT: addiu $3, $zero, 65535
+; LE-R6-NEXT: and $2, $2, $3
+; LE-R6-NEXT: andi $3, $1, 255
+; LE-R6-NEXT: jrc $ra
+ %v = load i40, ptr %p, align 1
+ %r = zext i40 %v to i64
+ ret i64 %r
+}
+
+define i64 @load_i64(ptr %p) {
+; BE-LABEL: load_i64:
+; BE: # %bb.0:
+; BE-NEXT: # implicit-def: $v1
+; BE-NEXT: lwl $3, 4($4)
+; BE-NEXT: lwr $3, 7($4)
+; BE-NEXT: # implicit-def: $v0
+; BE-NEXT: lwl $2, 0($4)
+; BE-NEXT: lwr $2, 3($4)
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: load_i64:
+; LE: # %bb.0:
+; LE-NEXT: # implicit-def: $v0
+; LE-NEXT: lwl $2, 3($4)
+; LE-NEXT: lwr $2, 0($4)
+; LE-NEXT: # implicit-def: $v1
+; LE-NEXT: lwl $3, 7($4)
+; LE-NEXT: lwr $3, 4($4)
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: load_i64:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: lw $3, 4($4)
+; BE-R6-NEXT: lw $2, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: load_i64:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: lw $2, 0($4)
+; LE-R6-NEXT: lw $3, 4($4)
+; LE-R6-NEXT: jrc $ra
+ %v = load i64, ptr %p, align 1
+ ret i64 %v
+}
+
+define void @store_i16(ptr %p, i32 %x) {
+; BE-LABEL: store_i16:
+; BE: # %bb.0:
+; BE-NEXT: sb $5, 1($4)
+; BE-NEXT: srl $1, $5, 8
+; BE-NEXT: sb $1, 0($4)
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: store_i16:
+; LE: # %bb.0:
+; LE-NEXT: sb $5, 0($4)
+; LE-NEXT: srl $1, $5, 8
+; LE-NEXT: sb $1, 1($4)
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: store_i16:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: sh $5, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: store_i16:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: sh $5, 0($4)
+; LE-R6-NEXT: jrc $ra
+ %v = trunc i32 %x to i16
+ store i16 %v, ptr %p, align 1
+ ret void
+}
+
+define void @store_i24(ptr %p, i32 %x) {
+; BE-LABEL: store_i24:
+; BE: # %bb.0:
+; BE-NEXT: ori $1, $zero, 1
+; BE-NEXT: addu $1, $4, $1
+; BE-NEXT: sb $5, 1($1)
+; BE-NEXT: srl $1, $5, 8
+; BE-NEXT: sb $1, 1($4)
+; BE-NEXT: srl $1, $5, 16
+; BE-NEXT: sb $1, 0($4)
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: store_i24:
+; LE: # %bb.0:
+; LE-NEXT: sb $5, 0($4)
+; LE-NEXT: srl $1, $5, 8
+; LE-NEXT: sb $1, 1($4)
+; LE-NEXT: srl $1, $5, 16
+; LE-NEXT: sb $1, 2($4)
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: store_i24:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: sh $5, 1($4)
+; BE-R6-NEXT: srl $1, $5, 16
+; BE-R6-NEXT: sb $1, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: store_i24:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: sh $5, 0($4)
+; LE-R6-NEXT: srl $1, $5, 16
+; LE-R6-NEXT: sb $1, 2($4)
+; LE-R6-NEXT: jrc $ra
+ %v = trunc i32 %x to i24
+ store i24 %v, ptr %p, align 1
+ ret void
+}
+
+define void @store_i40(ptr %p, i64 %x) {
+; BE-LABEL: store_i40:
+; BE: # %bb.0:
+; BE-NEXT: swl $7, 1($4)
+; BE-NEXT: swr $7, 4($4)
+; BE-NEXT: sb $6, 0($4)
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: store_i40:
+; LE: # %bb.0:
+; LE-NEXT: swl $6, 3($4)
+; LE-NEXT: swr $6, 0($4)
+; LE-NEXT: sb $7, 4($4)
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: store_i40:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: sw $7, 1($4)
+; BE-R6-NEXT: sb $6, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: store_i40:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: sw $6, 0($4)
+; LE-R6-NEXT: sb $7, 4($4)
+; LE-R6-NEXT: jrc $ra
+ %v = trunc i64 %x to i40
+ store i40 %v, ptr %p, align 1
+ ret void
+}
+
+define void @store_i64(ptr %p, i64 %x) {
+; BE-LABEL: store_i64:
+; BE: # %bb.0:
+; BE-NEXT: swl $7, 4($4)
+; BE-NEXT: swr $7, 7($4)
+; BE-NEXT: swl $6, 0($4)
+; BE-NEXT: swr $6, 3($4)
+; BE-NEXT: jr $ra
+; BE-NEXT: nop
+;
+; LE-LABEL: store_i64:
+; LE: # %bb.0:
+; LE-NEXT: swl $6, 3($4)
+; LE-NEXT: swr $6, 0($4)
+; LE-NEXT: swl $7, 7($4)
+; LE-NEXT: swr $7, 4($4)
+; LE-NEXT: jr $ra
+; LE-NEXT: nop
+;
+; BE-R6-LABEL: store_i64:
+; BE-R6: # %bb.0:
+; BE-R6-NEXT: sw $7, 4($4)
+; BE-R6-NEXT: sw $6, 0($4)
+; BE-R6-NEXT: jrc $ra
+;
+; LE-R6-LABEL: store_i64:
+; LE-R6: # %bb.0:
+; LE-R6-NEXT: sw $6, 0($4)
+; LE-R6-NEXT: sw $7, 4($4)
+; LE-R6-NEXT: jrc $ra
+ store i64 %x, ptr %p, align 1
+ ret void
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_constants.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_constants.ll
index 85feeda82e254..72fc17bc59ac5 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_constants.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/float_constants.ll
@@ -1,5 +1,6 @@
; 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,FP32
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32,FP32
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -mattr=+fp64,+mips32r2 -global-isel -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=MIPS32,FP64
define float @e_single_precision() {
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_store_vec.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_store_vec.ll
index c09353f3e1ff7..09ecc26d966cf 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_store_vec.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/load_store_vec.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=P5600
+; RUN: llc -O0 -mtriple=mips-linux-gnu -global-isel -global-isel-abort=1 -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=P5600
define void @load_store_v16i8(ptr %a, ptr %b) {
; P5600-LABEL: load_store_v16i8:
More information about the llvm-commits
mailing list