1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[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

llvm-svn: 365494
This commit is contained in:
Petar Avramovic 2019-07-09 14:36:17 +00:00
parent 6dec58dd68
commit 3836a24c30
6 changed files with 564 additions and 27 deletions

View 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;
}
}
}

View 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})

View 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.

View 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
@ -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
...

View 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
}

View 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
@ -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
...