From 47da14c083285a03aed3b237a2d4c463b13940a3 Mon Sep 17 00:00:00 2001 From: Petar Avramovic Date: Tue, 9 Jul 2019 14:36:17 +0000 Subject: [PATCH] [MIPS GlobalISel] Register bank select for G_PHI. Select i64 phi Select gprb or fprb when def/use register operand of G_PHI is used/defined by either: copy to/from physical register or instruction with only one mapping available for that use/def operand. Integer s64 phi 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. Differential Revision: https://reviews.llvm.org/D64351 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365494 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 28 +++ lib/Target/Mips/MipsLegalizerInfo.cpp | 2 +- lib/Target/Mips/MipsRegisterBankInfo.cpp | 37 +++- test/CodeGen/Mips/GlobalISel/legalizer/phi.mir | 233 +++++++++++++++++++-- test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll | 69 +++++- test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir | 222 +++++++++++++++++++- 6 files changed, 564 insertions(+), 27 deletions(-) diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index f44cdefe309..daea9a9b5fe 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -708,6 +708,34 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, narrowScalarDst(MI, NarrowTy, 0, TargetOpcode::G_ZEXT); Observer.changedInstr(MI); return Legalized; + case TargetOpcode::G_PHI: { + unsigned NumParts = SizeOp0 / NarrowSize; + SmallVector DstRegs; + SmallVector, 2> SrcRegs; + DstRegs.resize(NumParts); + SrcRegs.resize(MI.getNumOperands() / 2); + Observer.changingInstr(MI); + for (unsigned i = 1; i < MI.getNumOperands(); i += 2) { + MachineBasicBlock &OpMBB = *MI.getOperand(i + 1).getMBB(); + MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminator()); + extractParts(MI.getOperand(i).getReg(), NarrowTy, NumParts, + SrcRegs[i / 2]); + } + MachineBasicBlock &MBB = *MI.getParent(); + MIRBuilder.setInsertPt(MBB, MI); + for (unsigned i = 0; i < NumParts; ++i) { + DstRegs[i] = MRI.createGenericVirtualRegister(NarrowTy); + MachineInstrBuilder MIB = + MIRBuilder.buildInstr(TargetOpcode::G_PHI).addDef(DstRegs[i]); + for (unsigned j = 1; j < MI.getNumOperands(); j += 2) + MIB.addUse(SrcRegs[j / 2][i]).add(MI.getOperand(j + 1)); + } + MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI()); + MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs); + Observer.changedInstr(MI); + MI.eraseFromParent(); + return Legalized; + } } } diff --git a/lib/Target/Mips/MipsLegalizerInfo.cpp b/lib/Target/Mips/MipsLegalizerInfo.cpp index 60185a74d39..621f3e54a04 100644 --- a/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -64,7 +64,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { .minScalar(0, s32); getActionDefinitionsBuilder(G_PHI) - .legalFor({p0, s32}) + .legalFor({p0, s32, s64}) .minScalar(0, s32); getActionDefinitionsBuilder({G_AND, G_OR, G_XOR}) diff --git a/lib/Target/Mips/MipsRegisterBankInfo.cpp b/lib/Target/Mips/MipsRegisterBankInfo.cpp index cc0cd5551fa..7f570207f59 100644 --- a/lib/Target/Mips/MipsRegisterBankInfo.cpp +++ b/lib/Target/Mips/MipsRegisterBankInfo.cpp @@ -195,6 +195,13 @@ MipsRegisterBankInfo::AmbiguousRegDefUseContainer::AmbiguousRegDefUseContainer( if (MI->getOpcode() == TargetOpcode::G_STORE) addUseDef(MI->getOperand(0).getReg(), MRI); + if (MI->getOpcode() == TargetOpcode::G_PHI) { + addDefUses(MI->getOperand(0).getReg(), MRI); + + for (unsigned i = 1; i < MI->getNumOperands(); i += 2) + addUseDef(MI->getOperand(i).getReg(), MRI); + } + if (MI->getOpcode() == TargetOpcode::G_SELECT) { addDefUses(MI->getOperand(0).getReg(), MRI); @@ -305,9 +312,12 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); - const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); - if (Mapping.isValid()) - return Mapping; + if (MI.getOpcode() != TargetOpcode::G_PHI) { + const RegisterBankInfo::InstructionMapping &Mapping = + getInstrMappingImpl(MI); + if (Mapping.isValid()) + return Mapping; + } using namespace TargetOpcode; @@ -384,6 +394,26 @@ MipsRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { } break; } + case G_PHI: { + 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); + } + + // PHI is copylike and should have one regbank in mapping for def register. + if (InstTy == InstType::Integer && Size == 64) { // fprb + OperandsMapping = + getOperandsMapping({&Mips::ValueMappings[Mips::DPRIdx]}); + return getInstructionMapping(CustomMappingID, /*Cost=*/1, OperandsMapping, + /*NumOperands=*/1); + } + // Use default handling for PHI, i.e. set reg bank of def operand to match + // register banks of use operands. + const RegisterBankInfo::InstructionMapping &Mapping = + getInstrMappingImpl(MI); + return Mapping; + } case G_SELECT: { unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); InstType InstTy = InstType::Integer; @@ -545,6 +575,7 @@ void MipsRegisterBankInfo::applyMappingImpl( switch (MI.getOpcode()) { case TargetOpcode::G_LOAD: case TargetOpcode::G_STORE: + case TargetOpcode::G_PHI: case TargetOpcode::G_SELECT: { Helper.narrowScalar(MI, 0, LLT::scalar(32)); // Handle new instructions. diff --git a/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir b/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir index a3e5bd9fa5a..f8cca3ace6d 100644 --- a/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir +++ b/test/CodeGen/Mips/GlobalISel/legalizer/phi.mir @@ -2,7 +2,7 @@ # RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32 --- | - define i1 @test_i1(i1 %cnd, i1 %a, i1 %b) { + define i1 @phi_i1(i1 %cnd, i1 %a, i1 %b) { entry: br i1 %cnd, label %cond.true, label %cond.false @@ -17,7 +17,7 @@ ret i1 %cond } - define i8 @test_i8(i1 %cnd, i8 %a, i8 %b) { + define i8 @phi_i8(i1 %cnd, i8 %a, i8 %b) { entry: br i1 %cnd, label %cond.true, label %cond.false @@ -32,7 +32,7 @@ ret i8 %cond } - define i16 @test_i16(i1 %cnd, i16 %a, i16 %b) { + define i16 @phi_i16(i1 %cnd, i16 %a, i16 %b) { entry: br i1 %cnd, label %cond.true, label %cond.false @@ -47,7 +47,7 @@ ret i16 %cond } - define i32 @test_i32(i1 %cnd, i32 %a, i32 %b) { + define i32 @phi_i32(i1 %cnd, i32 %a, i32 %b) { entry: br i1 %cnd, label %cond.true, label %cond.false @@ -62,13 +62,58 @@ ret i32 %cond } + define i64 @phi_i64(i1 %cnd, i64 %a, i64 %b) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi i64 [ %a, %cond.true ], [ %b, %cond.false ] + ret i64 %cond + } + + define float @phi_float(i1 %cnd, float %a, float %b) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi float [ %a, %cond.true ], [ %b, %cond.false ] + ret float %cond + } + + define double @phi_double(double %a, double %b, i1 %cnd) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi double [ %a, %cond.true ], [ %b, %cond.false ] + ret double %cond + } + ... --- -name: test_i1 +name: phi_i1 alignment: 2 tracksRegLiveness: true body: | - ; MIPS32-LABEL: name: test_i1 + ; MIPS32-LABEL: name: phi_i1 ; MIPS32: bb.0.entry: ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; MIPS32: liveins: $a0, $a1, $a2 @@ -117,11 +162,11 @@ body: | ... --- -name: test_i8 +name: phi_i8 alignment: 2 tracksRegLiveness: true body: | - ; MIPS32-LABEL: name: test_i8 + ; MIPS32-LABEL: name: phi_i8 ; MIPS32: bb.0.entry: ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; MIPS32: liveins: $a0, $a1, $a2 @@ -170,11 +215,11 @@ body: | ... --- -name: test_i16 +name: phi_i16 alignment: 2 tracksRegLiveness: true body: | - ; MIPS32-LABEL: name: test_i16 + ; MIPS32-LABEL: name: phi_i16 ; MIPS32: bb.0.entry: ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; MIPS32: liveins: $a0, $a1, $a2 @@ -223,11 +268,11 @@ body: | ... --- -name: test_i32 +name: phi_i32 alignment: 2 tracksRegLiveness: true body: | - ; MIPS32-LABEL: name: test_i32 + ; MIPS32-LABEL: name: phi_i32 ; MIPS32: bb.0.entry: ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; MIPS32: liveins: $a0, $a1, $a2 @@ -269,3 +314,167 @@ body: | RetRA implicit $v0 ... +--- +name: phi_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: | + ; MIPS32-LABEL: name: phi_i64 + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:_(s64) = G_PHI [[MV]](s64), %bb.1, [[MV1]](s64), %bb.2 + ; MIPS32: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[PHI]](s64) + ; MIPS32: $v0 = COPY [[UV]](s32) + ; MIPS32: $v1 = COPY [[UV1]](s32) + ; MIPS32: RetRA implicit $v0, implicit $v1 + bb.1.entry: + liveins: $a0, $a2, $a3 + + %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) + G_BRCOND %0(s1), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %10:_(s64) = G_PHI %1(s64), %bb.2, %2(s64), %bb.3 + %11:_(s32), %12:_(s32) = G_UNMERGE_VALUES %10(s64) + $v0 = COPY %11(s32) + $v1 = COPY %12(s32) + RetRA implicit $v0, implicit $v1 + +... +--- +name: phi_float +alignment: 2 +tracksRegLiveness: true +body: | + ; MIPS32-LABEL: name: phi_float + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:_(s32) = G_PHI [[MTC1_]](s32), %bb.1, [[MTC1_1]](s32), %bb.2 + ; MIPS32: $f0 = COPY [[PHI]](s32) + ; MIPS32: RetRA implicit $f0 + bb.1.entry: + liveins: $a0, $a1, $a2 + + %3:_(s32) = COPY $a0 + %0:_(s1) = G_TRUNC %3(s32) + %1:fgr32(s32) = MTC1 $a1 + %2:fgr32(s32) = MTC1 $a2 + G_BRCOND %0(s1), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %4:_(s32) = G_PHI %1(s32), %bb.2, %2(s32), %bb.3 + $f0 = COPY %4(s32) + RetRA implicit $f0 + +... +--- +name: phi_double +alignment: 2 +tracksRegLiveness: true +fixedStack: + - { id: 0, offset: 16, size: 4, alignment: 8, isImmutable: true } +body: | + ; MIPS32-LABEL: name: phi_double + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:_(s64) = G_PHI [[COPY]](s64), %bb.1, [[COPY1]](s64), %bb.2 + ; MIPS32: $d0 = COPY [[PHI]](s64) + ; MIPS32: RetRA implicit $d0 + bb.1.entry: + liveins: $d6, $d7 + + %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) + G_BRCOND %2(s1), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %5:_(s64) = G_PHI %0(s64), %bb.2, %1(s64), %bb.3 + $d0 = COPY %5(s64) + RetRA implicit $d0 + +... diff --git a/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll b/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll index 4b52268e245..fa2196ea3cd 100644 --- a/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll +++ b/test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll @@ -1,8 +1,8 @@ ; 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 -define i1 @test_i1(i1 %cnd, i1 %a, i1 %b) { -; MIPS32-LABEL: test_i1: +define i1 @phi_i1(i1 %cnd, i1 %a, i1 %b) { +; MIPS32-LABEL: phi_i1: ; MIPS32: # %bb.0: # %entry ; MIPS32-NEXT: addiu $sp, $sp, -16 ; MIPS32-NEXT: .cfi_def_cfa_offset 16 @@ -43,8 +43,8 @@ cond.end: ret i1 %cond } -define i8 @test_i8(i1 %cnd, i8 %a, i8 %b) { -; MIPS32-LABEL: test_i8: +define i8 @phi_i8(i1 %cnd, i8 %a, i8 %b) { +; MIPS32-LABEL: phi_i8: ; MIPS32: # %bb.0: # %entry ; MIPS32-NEXT: addiu $sp, $sp, -16 ; MIPS32-NEXT: .cfi_def_cfa_offset 16 @@ -85,8 +85,8 @@ cond.end: ret i8 %cond } -define i16 @test_i16(i1 %cnd, i16 %a, i16 %b) { -; MIPS32-LABEL: test_i16: +define i16 @phi_i16(i1 %cnd, i16 %a, i16 %b) { +; MIPS32-LABEL: phi_i16: ; MIPS32: # %bb.0: # %entry ; MIPS32-NEXT: addiu $sp, $sp, -16 ; MIPS32-NEXT: .cfi_def_cfa_offset 16 @@ -127,8 +127,8 @@ cond.end: ret i16 %cond } -define i32 @test_i32(i1 %cnd, i32 %a, i32 %b) { -; MIPS32-LABEL: test_i32: +define i32 @phi_i32(i1 %cnd, i32 %a, i32 %b) { +; MIPS32-LABEL: phi_i32: ; MIPS32: # %bb.0: # %entry ; MIPS32-NEXT: addiu $sp, $sp, -16 ; MIPS32-NEXT: .cfi_def_cfa_offset 16 @@ -168,3 +168,56 @@ cond.end: %cond = phi i32 [ %a, %cond.true ], [ %b, %cond.false ] ret i32 %cond } + +define i64 @phi_i64(i1 %cnd, i64 %a, i64 %b) { +; MIPS32-LABEL: phi_i64: +; MIPS32: # %bb.0: # %entry +; MIPS32-NEXT: addiu $sp, $sp, -24 +; MIPS32-NEXT: .cfi_def_cfa_offset 24 +; MIPS32-NEXT: addiu $1, $sp, 40 +; MIPS32-NEXT: lw $1, 0($1) +; MIPS32-NEXT: addiu $2, $sp, 44 +; MIPS32-NEXT: lw $2, 0($2) +; MIPS32-NEXT: ori $3, $zero, 1 +; MIPS32-NEXT: and $3, $4, $3 +; MIPS32-NEXT: sw $1, 20($sp) # 4-byte Folded Spill +; MIPS32-NEXT: sw $6, 16($sp) # 4-byte Folded Spill +; MIPS32-NEXT: sw $7, 12($sp) # 4-byte Folded Spill +; MIPS32-NEXT: sw $2, 8($sp) # 4-byte Folded Spill +; MIPS32-NEXT: bnez $3, $BB4_2 +; MIPS32-NEXT: nop +; MIPS32-NEXT: # %bb.1: # %entry +; MIPS32-NEXT: j $BB4_3 +; MIPS32-NEXT: nop +; MIPS32-NEXT: $BB4_2: # %cond.true +; MIPS32-NEXT: lw $1, 16($sp) # 4-byte Folded Reload +; MIPS32-NEXT: lw $2, 12($sp) # 4-byte Folded Reload +; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS32-NEXT: sw $2, 0($sp) # 4-byte Folded Spill +; MIPS32-NEXT: j $BB4_4 +; MIPS32-NEXT: nop +; MIPS32-NEXT: $BB4_3: # %cond.false +; MIPS32-NEXT: lw $1, 20($sp) # 4-byte Folded Reload +; MIPS32-NEXT: lw $2, 8($sp) # 4-byte Folded Reload +; MIPS32-NEXT: sw $1, 4($sp) # 4-byte Folded Spill +; MIPS32-NEXT: sw $2, 0($sp) # 4-byte Folded Spill +; MIPS32-NEXT: $BB4_4: # %cond.end +; MIPS32-NEXT: lw $1, 0($sp) # 4-byte Folded Reload +; MIPS32-NEXT: lw $2, 4($sp) # 4-byte Folded Reload +; MIPS32-NEXT: move $3, $1 +; MIPS32-NEXT: addiu $sp, $sp, 24 +; MIPS32-NEXT: jr $ra +; MIPS32-NEXT: nop +entry: + br i1 %cnd, label %cond.true, label %cond.false + +cond.true: + br label %cond.end + +cond.false: + br label %cond.end + +cond.end: + %cond = phi i64 [ %a, %cond.true ], [ %b, %cond.false ] + ret i64 %cond +} diff --git a/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir b/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir index ef5cedbc5e1..20379231560 100644 --- a/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir +++ b/test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir @@ -2,7 +2,7 @@ # RUN: llc -O0 -mtriple=mipsel-linux-gnu -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=MIPS32 --- | - define i32 @test_i32(i1 %cnd, i32 %a, i32 %b) { + define i32 @phi_i32(i1 %cnd, i32 %a, i32 %b) { entry: br i1 %cnd, label %cond.true, label %cond.false @@ -17,14 +17,59 @@ ret i32 %cond } + define i64 @phi_i64(i1 %cnd, i64 %a, i64 %b) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi i64 [ %a, %cond.true ], [ %b, %cond.false ] + ret i64 %cond + } + + define float @phi_float(i1 %cnd, float %a, float %b) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi float [ %a, %cond.true ], [ %b, %cond.false ] + ret float %cond + } + + define double @phi_double(double %a, double %b, i1 %cnd) { + entry: + br i1 %cnd, label %cond.true, label %cond.false + + cond.true: ; preds = %entry + br label %cond.end + + cond.false: ; preds = %entry + br label %cond.end + + cond.end: ; preds = %cond.false, %cond.true + %cond = phi double [ %a, %cond.true ], [ %b, %cond.false ] + ret double %cond + } + ... --- -name: test_i32 +name: phi_i32 alignment: 2 legalized: true tracksRegLiveness: true body: | - ; MIPS32-LABEL: name: test_i32 + ; MIPS32-LABEL: name: phi_i32 ; MIPS32: bb.0.entry: ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; MIPS32: liveins: $a0, $a1, $a2 @@ -68,3 +113,174 @@ body: | RetRA implicit $v0 ... +--- +name: phi_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: | + ; MIPS32-LABEL: name: phi_i64 + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:gprb(s32) = G_PHI [[COPY1]](s32), %bb.1, [[LOAD]](s32), %bb.2 + ; MIPS32: [[PHI1:%[0-9]+]]:gprb(s32) = G_PHI [[COPY2]](s32), %bb.1, [[LOAD1]](s32), %bb.2 + ; MIPS32: $v0 = COPY [[PHI]](s32) + ; MIPS32: $v1 = COPY [[PHI1]](s32) + ; MIPS32: RetRA implicit $v0, implicit $v1 + bb.1.entry: + liveins: $a0, $a2, $a3 + + %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 + G_BRCOND %13(s32), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %10:_(s64) = G_PHI %1(s64), %bb.2, %2(s64), %bb.3 + %11:_(s32), %12:_(s32) = G_UNMERGE_VALUES %10(s64) + $v0 = COPY %11(s32) + $v1 = COPY %12(s32) + RetRA implicit $v0, implicit $v1 + +... +--- +name: phi_float +alignment: 2 +legalized: true +tracksRegLiveness: true +body: | + ; MIPS32-LABEL: name: phi_float + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:fprb(s32) = G_PHI [[MTC1_]](s32), %bb.1, [[MTC1_1]](s32), %bb.2 + ; MIPS32: $f0 = COPY [[PHI]](s32) + ; MIPS32: RetRA implicit $f0 + bb.1.entry: + liveins: $a0, $a1, $a2 + + %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 + G_BRCOND %5(s32), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %4:_(s32) = G_PHI %1(s32), %bb.2, %2(s32), %bb.3 + $f0 = COPY %4(s32) + RetRA implicit $f0 + +... +--- +name: phi_double +alignment: 2 +legalized: true +tracksRegLiveness: true +fixedStack: + - { id: 0, offset: 16, size: 4, alignment: 8, isImmutable: true } +body: | + ; MIPS32-LABEL: name: phi_double + ; MIPS32: bb.0.entry: + ; MIPS32: successors: %bb.1(0x40000000), %bb.2(0x40000000) + ; 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: G_BRCOND [[AND]](s32), %bb.1 + ; MIPS32: G_BR %bb.2 + ; MIPS32: bb.1.cond.true: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: G_BR %bb.3 + ; MIPS32: bb.2.cond.false: + ; MIPS32: successors: %bb.3(0x80000000) + ; MIPS32: bb.3.cond.end: + ; MIPS32: [[PHI:%[0-9]+]]:fprb(s64) = G_PHI [[COPY]](s64), %bb.1, [[COPY1]](s64), %bb.2 + ; MIPS32: $d0 = COPY [[PHI]](s64) + ; MIPS32: RetRA implicit $d0 + bb.1.entry: + liveins: $d6, $d7 + + %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 + G_BRCOND %6(s32), %bb.2 + G_BR %bb.3 + + bb.2.cond.true: + G_BR %bb.4 + + bb.3.cond.false: + + bb.4.cond.end: + %5:_(s64) = G_PHI %0(s64), %bb.2, %1(s64), %bb.3 + $d0 = COPY %5(s64) + RetRA implicit $d0 + +... -- 2.11.0