summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-07-09 14:30:29 +0000
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>2019-07-09 14:30:29 +0000
commitdbb6d01d340f5fecd0591f2ef25acb043bd6957b (patch)
tree2b994d1daf5a32f39ed1f7f8b8664a83dce04cdb
parent85ad662dfd573cb07e777383cfd0bb8f85c7b583 (diff)
downloadbcm5719-llvm-dbb6d01d340f5fecd0591f2ef25acb043bd6957b.tar.gz
bcm5719-llvm-dbb6d01d340f5fecd0591f2ef25acb043bd6957b.zip
[MIPS GlobalISel] Regbanks for G_SELECT. Select i64, f32 and f64 select
Select gprb or fprb when def/use register operand of G_SELECT is used/defined by either: copy to/from physical register or instruction with only one mapping available for that use/def operand. Integer s64 select is handled with narrowScalar when mapping is applied, produced artifacts are combined away. Manually set gprb to all register operands of instructions created during narrowScalar. For selection of floating point s32 or s64 select it is enough to set fprb of appropriate size and selectImpl will do the rest. Differential Revision: https://reviews.llvm.org/D64350 llvm-svn: 365492
-rw-r--r--llvm/lib/Target/Mips/MipsLegalizerInfo.cpp2
-rw-r--r--llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp42
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir152
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir110
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll56
-rw-r--r--llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir117
6 files changed, 449 insertions, 30 deletions
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index 9be50714579..60185a74d39 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -55,7 +55,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
.minScalar(0, s32);
getActionDefinitionsBuilder(G_SELECT)
- .legalForCartesianProduct({p0, s32}, {s32})
+ .legalForCartesianProduct({p0, s32, s64}, {s32})
.minScalar(0, s32)
.minScalar(1, s32);
diff --git a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
index eebd7fe10f5..cc0cd5551fa 100644
--- a/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsRegisterBankInfo.cpp
@@ -194,6 +194,13 @@ MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer(
if (MI->getOpcode() == TargetOpcode::G_STORE)
addUseDef(MI->getOperand(0).getReg(), MRI);
+
+ if (MI->getOpcode() == TargetOpcode::G_SELECT) {
+ addDefUses(MI->getOperand(0).getReg(), MRI);
+
+ addUseDef(MI->getOperand(2).getReg(), MRI);
+ addUseDef(MI->getOperand(3).getReg(), MRI);
+ }
}
bool MipsRegisterBankInfo::TypeInfoForMF::visit(const MachineInstr *MI) {
@@ -377,6 +384,31 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
}
break;
}
+ case G_SELECT: {
+ unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
+ InstType InstTy = InstType::Integer;
+ if (!MRI.getType(MI.getOperand(0).getReg()).isPointer()) {
+ InstTy = TI.determineInstType(&MI);
+ }
+
+ if (InstTy == InstType::FloatingPoint) { // fprb
+ const RegisterBankInfo::ValueMapping *Bank =
+ Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
+ : &Mips::ValueMappings[Mips::DPRIdx];
+ OperandsMapping = getOperandsMapping(
+ {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
+ break;
+ } else { // gprb
+ const RegisterBankInfo::ValueMapping *Bank =
+ Size <= 32 ? &Mips::ValueMappings[Mips::GPRIdx]
+ : &Mips::ValueMappings[Mips::DPRIdx];
+ OperandsMapping = getOperandsMapping(
+ {Bank, &Mips::ValueMappings[Mips::GPRIdx], Bank, Bank});
+ if (Size == 64)
+ MappingID = CustomMappingID;
+ }
+ break;
+ }
case G_UNMERGE_VALUES: {
OperandsMapping = getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
&Mips::ValueMappings[Mips::GPRIdx],
@@ -468,13 +500,6 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
&Mips::ValueMappings[Mips::GPRIdx],
&Mips::ValueMappings[Mips::GPRIdx]});
break;
- case G_SELECT:
- OperandsMapping =
- getOperandsMapping({&Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx],
- &Mips::ValueMappings[Mips::GPRIdx]});
- break;
default:
return getInvalidInstructionMapping();
}
@@ -519,7 +544,8 @@ void MipsRegisterBankInfo::applyMappingImpl(
switch (MI.getOpcode()) {
case TargetOpcode::G_LOAD:
- case TargetOpcode::G_STORE: {
+ case TargetOpcode::G_STORE:
+ case TargetOpcode::G_SELECT: {
Helper.narrowScalar(MI, 0, LLT::scalar(32));
// Handle new instructions.
while (!NewInstrs.empty()) {
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
index defc438c5a4..c0271fcbc06 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/instruction-select/select.mir
@@ -1,9 +1,12 @@
# 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
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32FP32
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -mattr=+fp64,+mips32r2 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32FP64
--- |
define void @select_i32() {entry: ret void}
define void @select_ptr() {entry: ret void}
+ define void @select_float() {entry: ret void}
+ define void @select_double() {entry: ret void}
...
---
@@ -16,16 +19,26 @@ body: |
bb.1.entry:
liveins: $a0, $a1, $a2
- ; MIPS32-LABEL: name: select_i32
- ; MIPS32: liveins: $a0, $a1, $a2
- ; MIPS32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; MIPS32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
- ; MIPS32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
- ; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
- ; MIPS32: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
- ; MIPS32: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
- ; MIPS32: $v0 = COPY [[MOVN_I_I]]
- ; MIPS32: RetRA implicit $v0
+ ; MIPS32FP32-LABEL: name: select_i32
+ ; MIPS32FP32: liveins: $a0, $a1, $a2
+ ; MIPS32FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; MIPS32FP32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
+ ; MIPS32FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP32: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP32: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
+ ; MIPS32FP32: $v0 = COPY [[MOVN_I_I]]
+ ; MIPS32FP32: RetRA implicit $v0
+ ; MIPS32FP64-LABEL: name: select_i32
+ ; MIPS32FP64: liveins: $a0, $a1, $a2
+ ; MIPS32FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; MIPS32FP64: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
+ ; MIPS32FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP64: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP64: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
+ ; MIPS32FP64: $v0 = COPY [[MOVN_I_I]]
+ ; MIPS32FP64: RetRA implicit $v0
%3:gprb(s32) = COPY $a0
%1:gprb(s32) = COPY $a1
%2:gprb(s32) = COPY $a2
@@ -47,16 +60,26 @@ body: |
bb.1.entry:
liveins: $a0, $a1, $a2
- ; MIPS32-LABEL: name: select_ptr
- ; MIPS32: liveins: $a0, $a1, $a2
- ; MIPS32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
- ; MIPS32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
- ; MIPS32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
- ; MIPS32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
- ; MIPS32: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
- ; MIPS32: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
- ; MIPS32: $v0 = COPY [[MOVN_I_I]]
- ; MIPS32: RetRA implicit $v0
+ ; MIPS32FP32-LABEL: name: select_ptr
+ ; MIPS32FP32: liveins: $a0, $a1, $a2
+ ; MIPS32FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; MIPS32FP32: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
+ ; MIPS32FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP32: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP32: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
+ ; MIPS32FP32: $v0 = COPY [[MOVN_I_I]]
+ ; MIPS32FP32: RetRA implicit $v0
+ ; MIPS32FP64-LABEL: name: select_ptr
+ ; MIPS32FP64: liveins: $a0, $a1, $a2
+ ; MIPS32FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; MIPS32FP64: [[COPY2:%[0-9]+]]:gpr32 = COPY $a2
+ ; MIPS32FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP64: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP64: [[MOVN_I_I:%[0-9]+]]:gpr32 = MOVN_I_I [[COPY1]], [[AND]], [[COPY2]]
+ ; MIPS32FP64: $v0 = COPY [[MOVN_I_I]]
+ ; MIPS32FP64: RetRA implicit $v0
%3:gprb(s32) = COPY $a0
%1:gprb(p0) = COPY $a1
%2:gprb(p0) = COPY $a2
@@ -68,3 +91,90 @@ body: |
RetRA implicit $v0
...
+---
+name: select_float
+alignment: 2
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1, $a2
+
+ ; MIPS32FP32-LABEL: name: select_float
+ ; MIPS32FP32: liveins: $a0, $a1, $a2
+ ; MIPS32FP32: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP32: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
+ ; MIPS32FP32: [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+ ; MIPS32FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP32: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP32: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[MTC1_]], [[AND]], [[MTC1_1]]
+ ; MIPS32FP32: $f0 = COPY [[MOVN_I_S]]
+ ; MIPS32FP32: RetRA implicit $f0
+ ; MIPS32FP64-LABEL: name: select_float
+ ; MIPS32FP64: liveins: $a0, $a1, $a2
+ ; MIPS32FP64: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; MIPS32FP64: [[MTC1_:%[0-9]+]]:fgr32 = MTC1 $a1
+ ; MIPS32FP64: [[MTC1_1:%[0-9]+]]:fgr32 = MTC1 $a2
+ ; MIPS32FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP64: [[AND:%[0-9]+]]:gpr32 = AND [[COPY]], [[ORi]]
+ ; MIPS32FP64: [[MOVN_I_S:%[0-9]+]]:fgr32 = MOVN_I_S [[MTC1_]], [[AND]], [[MTC1_1]]
+ ; MIPS32FP64: $f0 = COPY [[MOVN_I_S]]
+ ; MIPS32FP64: RetRA implicit $f0
+ %3:gprb(s32) = COPY $a0
+ %1:fgr32(s32) = MTC1 $a1
+ %2:fgr32(s32) = MTC1 $a2
+ %6:gprb(s32) = G_CONSTANT i32 1
+ %7:gprb(s32) = COPY %3(s32)
+ %5:gprb(s32) = G_AND %7, %6
+ %4:fprb(s32) = G_SELECT %5(s32), %1, %2
+ $f0 = COPY %4(s32)
+ RetRA implicit $f0
+
+...
+---
+name: select_double
+alignment: 2
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+fixedStack:
+ - { id: 0, offset: 16, size: 4, alignment: 8, isImmutable: true }
+body: |
+ bb.1.entry:
+ liveins: $d6, $d7
+
+ ; MIPS32FP32-LABEL: name: select_double
+ ; MIPS32FP32: liveins: $d6, $d7
+ ; MIPS32FP32: [[COPY:%[0-9]+]]:afgr64 = COPY $d6
+ ; MIPS32FP32: [[COPY1:%[0-9]+]]:afgr64 = COPY $d7
+ ; MIPS32FP32: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.0, 0
+ ; MIPS32FP32: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu]], 0 :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32FP32: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP32: [[AND:%[0-9]+]]:gpr32 = AND [[LW]], [[ORi]]
+ ; MIPS32FP32: [[MOVN_I_D32_:%[0-9]+]]:afgr64 = MOVN_I_D32 [[COPY]], [[AND]], [[COPY1]]
+ ; MIPS32FP32: $d0 = COPY [[MOVN_I_D32_]]
+ ; MIPS32FP32: RetRA implicit $d0
+ ; MIPS32FP64-LABEL: name: select_double
+ ; MIPS32FP64: liveins: $d6, $d7
+ ; MIPS32FP64: [[COPY:%[0-9]+]]:fgr64 = COPY $d6
+ ; MIPS32FP64: [[COPY1:%[0-9]+]]:fgr64 = COPY $d7
+ ; MIPS32FP64: [[ADDiu:%[0-9]+]]:gpr32 = ADDiu %fixed-stack.0, 0
+ ; MIPS32FP64: [[LW:%[0-9]+]]:gpr32 = LW [[ADDiu]], 0 :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32FP64: [[ORi:%[0-9]+]]:gpr32 = ORi $zero, 1
+ ; MIPS32FP64: [[AND:%[0-9]+]]:gpr32 = AND [[LW]], [[ORi]]
+ ; MIPS32FP64: [[MOVN_I_D64_:%[0-9]+]]:fgr64 = MOVN_I_D64 [[COPY]], [[AND]], [[COPY1]]
+ ; MIPS32FP64: $d0 = COPY [[MOVN_I_D64_]]
+ ; MIPS32FP64: RetRA implicit $d0
+ %0:fprb(s64) = COPY $d6
+ %1:fprb(s64) = COPY $d7
+ %4:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
+ %3:gprb(s32) = G_LOAD %4(p0) :: (load 4 from %fixed-stack.0, align 8)
+ %7:gprb(s32) = G_CONSTANT i32 1
+ %8:gprb(s32) = COPY %3(s32)
+ %6:gprb(s32) = G_AND %8, %7
+ %5:fprb(s64) = G_SELECT %6(s32), %0, %1
+ $d0 = COPY %5(s64)
+ RetRA implicit $d0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
index 249c4d3a7f2..8d5322dcfa4 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
@@ -7,6 +7,9 @@
define void @select_i32() {entry: ret void}
define void @select_ptr() {entry: ret void}
define void @select_with_negation() {entry: ret void}
+ define void @select_i64() {entry: ret void}
+ define void @select_float() {entry: ret void}
+ define void @select_double() {entry: ret void}
...
---
@@ -170,3 +173,110 @@ body: |
RetRA implicit $v0
...
+---
+name: select_i64
+alignment: 2
+tracksRegLiveness: true
+fixedStack:
+ - { id: 0, offset: 20, size: 4, alignment: 4, isImmutable: true }
+ - { id: 1, offset: 16, size: 4, alignment: 8, isImmutable: true }
+body: |
+ bb.1.entry:
+ liveins: $a0, $a2, $a3
+
+ ; MIPS32-LABEL: name: select_i64
+ ; MIPS32: liveins: $a0, $a2, $a3
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a2
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a3
+ ; MIPS32: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[COPY1]](s32), [[COPY2]](s32)
+ ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; MIPS32: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load 4 from %fixed-stack.1)
+ ; MIPS32: [[MV1:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[LOAD]](s32), [[LOAD1]](s32)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:_(s64) = G_SELECT [[AND]](s32), [[MV]], [[MV1]]
+ ; MIPS32: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[SELECT]](s64)
+ ; MIPS32: $v0 = COPY [[UV]](s32)
+ ; MIPS32: $v1 = COPY [[UV1]](s32)
+ ; MIPS32: RetRA implicit $v0, implicit $v1
+ %3:_(s32) = COPY $a0
+ %0:_(s1) = G_TRUNC %3(s32)
+ %4:_(s32) = COPY $a2
+ %5:_(s32) = COPY $a3
+ %1:_(s64) = G_MERGE_VALUES %4(s32), %5(s32)
+ %8:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ %6:_(s32) = G_LOAD %8(p0) :: (load 4 from %fixed-stack.1, align 8)
+ %9:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %7:_(s32) = G_LOAD %9(p0) :: (load 4 from %fixed-stack.0)
+ %2:_(s64) = G_MERGE_VALUES %6(s32), %7(s32)
+ %10:_(s64) = G_SELECT %0(s1), %1, %2
+ %11:_(s32), %12:_(s32) = G_UNMERGE_VALUES %10(s64)
+ $v0 = COPY %11(s32)
+ $v1 = COPY %12(s32)
+ RetRA implicit $v0, implicit $v1
+
+...
+---
+name: select_float
+alignment: 2
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1, $a2
+
+ ; MIPS32-LABEL: name: select_float
+ ; MIPS32: liveins: $a0, $a1, $a2
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0
+ ; MIPS32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+ ; MIPS32: [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[AND]](s32), [[MTC1_]], [[MTC1_1]]
+ ; MIPS32: $f0 = COPY [[SELECT]](s32)
+ ; MIPS32: RetRA implicit $f0
+ %3:_(s32) = COPY $a0
+ %0:_(s1) = G_TRUNC %3(s32)
+ %1:fgr32(s32) = MTC1 $a1
+ %2:fgr32(s32) = MTC1 $a2
+ %4:_(s32) = G_SELECT %0(s1), %1, %2
+ $f0 = COPY %4(s32)
+ RetRA implicit $f0
+
+...
+---
+name: select_double
+alignment: 2
+tracksRegLiveness: true
+fixedStack:
+ - { id: 0, offset: 16, size: 4, alignment: 8, isImmutable: true }
+body: |
+ bb.1.entry:
+ liveins: $d6, $d7
+
+ ; MIPS32-LABEL: name: select_double
+ ; MIPS32: liveins: $d6, $d7
+ ; MIPS32: [[COPY:%[0-9]+]]:_(s64) = COPY $d6
+ ; MIPS32: [[COPY1:%[0-9]+]]:_(s64) = COPY $d7
+ ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; MIPS32: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY [[LOAD]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY2]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:_(s64) = G_SELECT [[AND]](s32), [[COPY]], [[COPY1]]
+ ; MIPS32: $d0 = COPY [[SELECT]](s64)
+ ; MIPS32: RetRA implicit $d0
+ %0:_(s64) = COPY $d6
+ %1:_(s64) = COPY $d7
+ %4:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %3:_(s32) = G_LOAD %4(p0) :: (load 4 from %fixed-stack.0, align 8)
+ %2:_(s1) = G_TRUNC %3(s32)
+ %5:_(s64) = G_SELECT %2(s1), %0, %1
+ $d0 = COPY %5(s64)
+ RetRA implicit $d0
+
+...
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
index 1aa2e421aaf..5c4338228fe 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
@@ -74,3 +74,59 @@ entry:
%cond = select i1 %lneg, i32 %x, i32 %y
ret i32 %cond
}
+
+define i64 @select_i64(i1 %test, i64 %a, i64 %b) {
+; MIPS32-LABEL: select_i64:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: addiu $sp, $sp, -8
+; MIPS32-NEXT: .cfi_def_cfa_offset 8
+; MIPS32-NEXT: addiu $1, $sp, 24
+; MIPS32-NEXT: lw $1, 0($1)
+; MIPS32-NEXT: addiu $2, $sp, 28
+; MIPS32-NEXT: lw $2, 0($2)
+; MIPS32-NEXT: ori $3, $zero, 1
+; MIPS32-NEXT: and $3, $4, $3
+; MIPS32-NEXT: movn $1, $6, $3
+; MIPS32-NEXT: movn $2, $7, $3
+; MIPS32-NEXT: sw $2, 4($sp) # 4-byte Folded Spill
+; MIPS32-NEXT: move $2, $1
+; MIPS32-NEXT: lw $3, 4($sp) # 4-byte Folded Reload
+; MIPS32-NEXT: addiu $sp, $sp, 8
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %cond = select i1 %test, i64 %a, i64 %b
+ ret i64 %cond
+}
+
+define float @select_float(i1 %test, float %a, float %b) {
+; MIPS32-LABEL: select_float:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: mtc1 $5, $f0
+; MIPS32-NEXT: mtc1 $6, $f1
+; MIPS32-NEXT: ori $1, $zero, 1
+; MIPS32-NEXT: and $1, $4, $1
+; MIPS32-NEXT: movn.s $f1, $f0, $1
+; MIPS32-NEXT: mov.s $f0, $f1
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %cond = select i1 %test, float %a, float %b
+ ret float %cond
+}
+
+define double @select_double(double %a, double %b, i1 %test) {
+; MIPS32-LABEL: select_double:
+; MIPS32: # %bb.0: # %entry
+; MIPS32-NEXT: addiu $1, $sp, 16
+; MIPS32-NEXT: lw $1, 0($1)
+; MIPS32-NEXT: ori $2, $zero, 1
+; MIPS32-NEXT: and $1, $1, $2
+; MIPS32-NEXT: movn.d $f14, $f12, $1
+; MIPS32-NEXT: mov.d $f0, $f14
+; MIPS32-NEXT: jr $ra
+; MIPS32-NEXT: nop
+entry:
+ %cond = select i1 %test, double %a, double %b
+ ret double %cond
+}
diff --git a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
index 98aae8a7b9d..2ae08ac4ddd 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
+++ b/llvm/test/CodeGen/Mips/GlobalISel/regbankselect/select.mir
@@ -4,6 +4,9 @@
define void @select_i32(i32, i32) {entry: ret void}
define void @select_ptr(i32, i32) {entry: ret void}
+ define void @select_i64() {entry: ret void}
+ define void @select_float() {entry: ret void}
+ define void @select_double() {entry: ret void}
...
---
@@ -68,3 +71,117 @@ body: |
RetRA implicit $v0
...
+---
+name: select_i64
+alignment: 2
+legalized: true
+tracksRegLiveness: true
+fixedStack:
+ - { id: 0, offset: 20, size: 4, alignment: 4, isImmutable: true }
+ - { id: 1, offset: 16, size: 4, alignment: 8, isImmutable: true }
+body: |
+ bb.1.entry:
+ liveins: $a0, $a2, $a3
+
+ ; MIPS32-LABEL: name: select_i64
+ ; MIPS32: liveins: $a0, $a2, $a3
+ ; MIPS32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+ ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY $a2
+ ; MIPS32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY $a3
+ ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; MIPS32: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32: [[FRAME_INDEX1:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.1
+ ; MIPS32: [[LOAD1:%[0-9]+]]:gprb(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (load 4 from %fixed-stack.1)
+ ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY3:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY3]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY1]], [[LOAD]]
+ ; MIPS32: [[SELECT1:%[0-9]+]]:gprb(s32) = G_SELECT [[AND]](s32), [[COPY2]], [[LOAD1]]
+ ; MIPS32: $v0 = COPY [[SELECT]](s32)
+ ; MIPS32: $v1 = COPY [[SELECT1]](s32)
+ ; MIPS32: RetRA implicit $v0, implicit $v1
+ %3:_(s32) = COPY $a0
+ %4:_(s32) = COPY $a2
+ %5:_(s32) = COPY $a3
+ %1:_(s64) = G_MERGE_VALUES %4(s32), %5(s32)
+ %8:_(p0) = G_FRAME_INDEX %fixed-stack.1
+ %6:_(s32) = G_LOAD %8(p0) :: (load 4 from %fixed-stack.1, align 8)
+ %9:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %7:_(s32) = G_LOAD %9(p0) :: (load 4 from %fixed-stack.0)
+ %2:_(s64) = G_MERGE_VALUES %6(s32), %7(s32)
+ %14:_(s32) = G_CONSTANT i32 1
+ %15:_(s32) = COPY %3(s32)
+ %13:_(s32) = G_AND %15, %14
+ %10:_(s64) = G_SELECT %13(s32), %1, %2
+ %11:_(s32), %12:_(s32) = G_UNMERGE_VALUES %10(s64)
+ $v0 = COPY %11(s32)
+ $v1 = COPY %12(s32)
+ RetRA implicit $v0, implicit $v1
+
+...
+---
+name: select_float
+alignment: 2
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1, $a2
+
+ ; MIPS32-LABEL: name: select_float
+ ; MIPS32: liveins: $a0, $a1, $a2
+ ; MIPS32: [[COPY:%[0-9]+]]:gprb(s32) = COPY $a0
+ ; MIPS32: [[MTC1_:%[0-9]+]]:fgr32(s32) = MTC1 $a1
+ ; MIPS32: [[MTC1_1:%[0-9]+]]:fgr32(s32) = MTC1 $a2
+ ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY1:%[0-9]+]]:gprb(s32) = COPY [[COPY]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY1]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:fprb(s32) = G_SELECT [[AND]](s32), [[MTC1_]], [[MTC1_1]]
+ ; MIPS32: $f0 = COPY [[SELECT]](s32)
+ ; MIPS32: RetRA implicit $f0
+ %3:_(s32) = COPY $a0
+ %1:fgr32(s32) = MTC1 $a1
+ %2:fgr32(s32) = MTC1 $a2
+ %6:_(s32) = G_CONSTANT i32 1
+ %7:_(s32) = COPY %3(s32)
+ %5:_(s32) = G_AND %7, %6
+ %4:_(s32) = G_SELECT %5(s32), %1, %2
+ $f0 = COPY %4(s32)
+ RetRA implicit $f0
+
+...
+---
+name: select_double
+alignment: 2
+legalized: true
+tracksRegLiveness: true
+fixedStack:
+ - { id: 0, offset: 16, size: 4, alignment: 8, isImmutable: true }
+body: |
+ bb.1.entry:
+ liveins: $d6, $d7
+
+ ; MIPS32-LABEL: name: select_double
+ ; MIPS32: liveins: $d6, $d7
+ ; MIPS32: [[COPY:%[0-9]+]]:fprb(s64) = COPY $d6
+ ; MIPS32: [[COPY1:%[0-9]+]]:fprb(s64) = COPY $d7
+ ; MIPS32: [[FRAME_INDEX:%[0-9]+]]:gprb(p0) = G_FRAME_INDEX %fixed-stack.0
+ ; MIPS32: [[LOAD:%[0-9]+]]:gprb(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (load 4 from %fixed-stack.0, align 8)
+ ; MIPS32: [[C:%[0-9]+]]:gprb(s32) = G_CONSTANT i32 1
+ ; MIPS32: [[COPY2:%[0-9]+]]:gprb(s32) = COPY [[LOAD]](s32)
+ ; MIPS32: [[AND:%[0-9]+]]:gprb(s32) = G_AND [[COPY2]], [[C]]
+ ; MIPS32: [[SELECT:%[0-9]+]]:fprb(s64) = G_SELECT [[AND]](s32), [[COPY]], [[COPY1]]
+ ; MIPS32: $d0 = COPY [[SELECT]](s64)
+ ; MIPS32: RetRA implicit $d0
+ %0:_(s64) = COPY $d6
+ %1:_(s64) = COPY $d7
+ %4:_(p0) = G_FRAME_INDEX %fixed-stack.0
+ %3:_(s32) = G_LOAD %4(p0) :: (load 4 from %fixed-stack.0, align 8)
+ %7:_(s32) = G_CONSTANT i32 1
+ %8:_(s32) = COPY %3(s32)
+ %6:_(s32) = G_AND %8, %7
+ %5:_(s64) = G_SELECT %6(s32), %0, %1
+ $d0 = COPY %5(s64)
+ RetRA implicit $d0
+
+...
OpenPOWER on IntegriCloud