]> granicus.if.org Git - llvm/commitdiff
[MIPS GlobalISel] Register bank select for G_PHI. Select i64 phi
authorPetar Avramovic <Petar.Avramovic@rt-rk.com>
Tue, 9 Jul 2019 14:36:17 +0000 (14:36 +0000)
committerPetar Avramovic <Petar.Avramovic@rt-rk.com>
Tue, 9 Jul 2019 14:36:17 +0000 (14:36 +0000)
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
lib/Target/Mips/MipsLegalizerInfo.cpp
lib/Target/Mips/MipsRegisterBankInfo.cpp
test/CodeGen/Mips/GlobalISel/legalizer/phi.mir
test/CodeGen/Mips/GlobalISel/llvm-ir/phi.ll
test/CodeGen/Mips/GlobalISel/regbankselect/phi.mir

index f44cdefe309c43c6336a5b1f910f421237c04ddd..daea9a9b5fe35bf58a51b661c00e64363a607590 100644 (file)
@@ -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<Register, 2> DstRegs;
+    SmallVector<SmallVector<Register, 2>, 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;
+  }
   }
 }
 
index 60185a74d39149e533b4fd03c2c3b585ff42eee2..621f3e54a04bf00f14ead8ccf3078815aae1cebd 100644 (file)
@@ -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})
index cc0cd5551fae9c96fd3a1fe8c00cbd5a8a060240..7f570207f593e0b737eeeac7bb09034ce3eae85c 100644 (file)
@@ -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.
index a3e5bd9fa5a3406a7ac896542f76ff79abc47060..f8cca3ace6d02655e183d0df9036d36c59b17517 100644 (file)
@@ -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
 
     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
+
+...
index 4b52268e245bbb7113ae7e69b458653387f1b682..fa2196ea3cd145ee7de158da587ebaec51a555f1 100644 (file)
@@ -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
+}
index ef5cedbc5e1e5288f5df63bd041ef7d449678df0..20379231560868aa3cab9b10a3b8057a0b40e5fe 100644 (file)
@@ -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
 
     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
+
+...