<div dir="ltr">Hi Aditya,<div><br></div><div>FYI, I submitted r311781 to fix the <a href="http://lab.llvm.org:8011/builders/sanitizer-ppc64le-linux/builds/3492">buildbot breakage</a> caused by this revision. Just removed the unused lambda capture.</div><div><br></div><div>- Matt</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 24, 2017 at 9:57 PM, Aditya Nandakumar via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: aditya_nandakumar<br>
Date: Thu Aug 24 21:57:27 2017<br>
New Revision: 311763<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=311763&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=311763&view=rev</a><br>
Log:<br>
[GISel]: Implement widenScalar for Legalizing G_PHI<br>
<br>
<a href="https://reviews.llvm.org/D37018" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D37018</a><br>
<br>
Added:<br>
llvm/trunk/test/CodeGen/<wbr>AArch64/GlobalISel/legalize-<wbr>phi.mir<br>
Modified:<br>
llvm/trunk/include/llvm/<wbr>CodeGen/GlobalISel/<wbr>MachineIRBuilder.h<br>
llvm/trunk/lib/CodeGen/<wbr>GlobalISel/LegalizerHelper.cpp<br>
llvm/trunk/lib/CodeGen/<wbr>GlobalISel/MachineIRBuilder.<wbr>cpp<br>
llvm/trunk/lib/Target/AArch64/<wbr>AArch64LegalizerInfo.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/<wbr>CodeGen/GlobalISel/<wbr>MachineIRBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=311763&r1=311762&r2=311763&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/CodeGen/GlobalISel/<wbr>MachineIRBuilder.h?rev=311763&<wbr>r1=311762&r2=311763&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/<wbr>CodeGen/GlobalISel/<wbr>MachineIRBuilder.h (original)<br>
+++ llvm/trunk/include/llvm/<wbr>CodeGen/GlobalISel/<wbr>MachineIRBuilder.h Thu Aug 24 21:57:27 2017<br>
@@ -84,6 +84,11 @@ class MachineIRBuilder {<br>
addUseFromArg(MIB, Arg1);<br>
addUsesFromArgs(MIB, std::forward<UseArgsTy>(Args).<wbr>..);<br>
}<br>
+ unsigned getRegFromArg(unsigned Reg) { return Reg; }<br>
+ unsigned getRegFromArg(const MachineInstrBuilder &MIB) {<br>
+ return MIB->getOperand(0).getReg();<br>
+ }<br>
+<br>
public:<br>
/// Some constructors for easy use.<br>
MachineIRBuilder() = default;<br>
@@ -372,7 +377,12 @@ public:<br>
/// \pre \p Op must be smaller than \p Res<br>
///<br>
/// \return The newly created instruction.<br>
+<br>
MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op);<br>
+ template <typename DstType, typename ArgType><br>
+ MachineInstrBuilder buildAnyExt(DstType &&Res, ArgType &&Arg) {<br>
+ return buildAnyExt(getDestFromArg(<wbr>Res), getRegFromArg(Arg));<br>
+ }<br>
<br>
/// Build and insert \p Res<def> = G_SEXT \p Op<br>
///<br>
@@ -422,6 +432,32 @@ public:<br>
/// \return The newly created instruction.<br>
MachineInstrBuilder buildZExtOrTrunc(unsigned Res, unsigned Op);<br>
<br>
+ // Build and insert \p Res<def> = G_ANYEXT \p Op, \p Res = G_TRUNC \p Op, or<br>
+ /// \p Res = COPY \p Op depending on the differing sizes of \p Res and \p Op.<br>
+ /// ///<br>
+ /// \pre setBasicBlock or setMI must have been called.<br>
+ /// \pre \p Res must be a generic virtual register with scalar or vector type.<br>
+ /// \pre \p Op must be a generic virtual register with scalar or vector type.<br>
+ ///<br>
+ /// \return The newly created instruction.<br>
+ template <typename DstTy, typename UseArgTy><br>
+ MachineInstrBuilder buildAnyExtOrTrunc(DstTy &&Dst, UseArgTy &&Use) {<br>
+ return buildAnyExtOrTrunc(<wbr>getDestFromArg(Dst), getRegFromArg(Use));<br>
+ }<br>
+ MachineInstrBuilder buildAnyExtOrTrunc(unsigned Res, unsigned Op);<br>
+<br>
+ /// Build and insert \p Res<def> = \p ExtOpc, \p Res = G_TRUNC \p<br>
+ /// Op, or \p Res = COPY \p Op depending on the differing sizes of \p Res and<br>
+ /// \p Op.<br>
+ /// ///<br>
+ /// \pre setBasicBlock or setMI must have been called.<br>
+ /// \pre \p Res must be a generic virtual register with scalar or vector type.<br>
+ /// \pre \p Op must be a generic virtual register with scalar or vector type.<br>
+ ///<br>
+ /// \return The newly created instruction.<br>
+ MachineInstrBuilder buildExtOrTrunc(unsigned ExtOpc, unsigned Res,<br>
+ unsigned Op);<br>
+<br>
/// Build and insert an appropriate cast between two registers of equal size.<br>
MachineInstrBuilder buildCast(unsigned Dst, unsigned Src);<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/<wbr>GlobalISel/LegalizerHelper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/LegalizerHelper.cpp?rev=311763&r1=311762&r2=311763&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>CodeGen/GlobalISel/<wbr>LegalizerHelper.cpp?rev=<wbr>311763&r1=311762&r2=311763&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/CodeGen/<wbr>GlobalISel/LegalizerHelper.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/<wbr>GlobalISel/LegalizerHelper.cpp Thu Aug 24 21:57:27 2017<br>
@@ -659,6 +659,37 @@ LegalizerHelper::widenScalar(<wbr>MachineInst<br>
MI.getOperand(2).setReg(<wbr>OffsetExt);<br>
return Legalized;<br>
}<br>
+ case TargetOpcode::G_PHI: {<br>
+ assert(TypeIdx == 0 && "Expecting only Idx 0");<br>
+ MachineFunction *MF = MI.getParent()->getParent();<br>
+ auto getExtendedReg = [this, MF, WideTy](unsigned Reg,<br>
+ MachineBasicBlock &MBB) {<br>
+ auto FirstTermIt = MBB.getFirstTerminator();<br>
+ MIRBuilder.setInsertPt(MBB, FirstTermIt);<br>
+ MachineInstr *DefMI = MRI.getVRegDef(Reg);<br>
+ MachineInstrBuilder MIB;<br>
+ if (DefMI->getOpcode() == TargetOpcode::G_TRUNC)<br>
+ MIB = MIRBuilder.buildAnyExtOrTrunc(<wbr>WideTy,<br>
+ DefMI->getOperand(1).getReg())<wbr>;<br>
+ else<br>
+ MIB = MIRBuilder.buildAnyExt(WideTy, Reg);<br>
+ return MIB->getOperand(0).getReg();<br>
+ };<br>
+ auto MIB = MIRBuilder.buildInstr(<wbr>TargetOpcode::G_PHI, WideTy);<br>
+ for (auto OpIt = MI.operands_begin() + 1, OpE = MI.operands_end();<br>
+ OpIt != OpE;) {<br>
+ unsigned Reg = OpIt++->getReg();<br>
+ MachineBasicBlock *OpMBB = OpIt++->getMBB();<br>
+ MIB.addReg(getExtendedReg(Reg, *OpMBB));<br>
+ MIB.addMBB(OpMBB);<br>
+ }<br>
+ auto *MBB = MI.getParent();<br>
+ MIRBuilder.setInsertPt(*MBB, MBB->getFirstNonPHI());<br>
+ MIRBuilder.buildTrunc(MI.<wbr>getOperand(0).getReg(),<br>
+ MIB->getOperand(0).getReg());<br>
+ MI.eraseFromParent();<br>
+ return Legalized;<br>
+ }<br>
}<br>
}<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/<wbr>GlobalISel/MachineIRBuilder.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=311763&r1=311762&r2=311763&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>CodeGen/GlobalISel/<wbr>MachineIRBuilder.cpp?rev=<wbr>311763&r1=311762&r2=311763&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/CodeGen/<wbr>GlobalISel/MachineIRBuilder.<wbr>cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/<wbr>GlobalISel/MachineIRBuilder.<wbr>cpp Thu Aug 24 21:57:27 2017<br>
@@ -346,14 +346,17 @@ MachineInstrBuilder MachineIRBuilder::bu<br>
return buildInstr(TargetOpcode::G_<wbr>ZEXT).addDef(Res).addUse(Op);<br>
}<br>
<br>
-MachineInstrBuilder MachineIRBuilder::<wbr>buildSExtOrTrunc(unsigned Res,<br>
- unsigned Op) {<br>
+MachineInstrBuilder<br>
+MachineIRBuilder::<wbr>buildExtOrTrunc(unsigned ExtOpc, unsigned Res, unsigned Op) {<br>
+ assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||<br>
+ TargetOpcode::G_SEXT == ExtOpc) &&<br>
+ "Expecting Extending Opc");<br>
assert(MRI->getType(Res).<wbr>isScalar() || MRI->getType(Res).isVector());<br>
assert(MRI->getType(Res).<wbr>isScalar() == MRI->getType(Op).isScalar());<br>
<br>
unsigned Opcode = TargetOpcode::COPY;<br>
if (MRI->getType(Res).<wbr>getSizeInBits() > MRI->getType(Op).<wbr>getSizeInBits())<br>
- Opcode = TargetOpcode::G_SEXT;<br>
+ Opcode = ExtOpc;<br>
else if (MRI->getType(Res).<wbr>getSizeInBits() < MRI->getType(Op).<wbr>getSizeInBits())<br>
Opcode = TargetOpcode::G_TRUNC;<br>
else<br>
@@ -362,20 +365,19 @@ MachineInstrBuilder MachineIRBuilder::bu<br>
return buildInstr(Opcode).addDef(Res)<wbr>.addUse(Op);<br>
}<br>
<br>
-MachineInstrBuilder MachineIRBuilder::<wbr>buildZExtOrTrunc(unsigned Res,<br>
+MachineInstrBuilder MachineIRBuilder::<wbr>buildSExtOrTrunc(unsigned Res,<br>
unsigned Op) {<br>
- assert(MRI->getType(Res).<wbr>isScalar() || MRI->getType(Res).isVector());<br>
- assert(MRI->getType(Res).<wbr>isScalar() == MRI->getType(Op).isScalar());<br>
+ return buildExtOrTrunc(TargetOpcode::<wbr>G_SEXT, Res, Op);<br>
+}<br>
<br>
- unsigned Opcode = TargetOpcode::COPY;<br>
- if (MRI->getType(Res).<wbr>getSizeInBits() > MRI->getType(Op).<wbr>getSizeInBits())<br>
- Opcode = TargetOpcode::G_ZEXT;<br>
- else if (MRI->getType(Res).<wbr>getSizeInBits() < MRI->getType(Op).<wbr>getSizeInBits())<br>
- Opcode = TargetOpcode::G_TRUNC;<br>
- else<br>
- assert(MRI->getType(Res) == MRI->getType(Op));<br>
+MachineInstrBuilder MachineIRBuilder::<wbr>buildZExtOrTrunc(unsigned Res,<br>
+ unsigned Op) {<br>
+ return buildExtOrTrunc(TargetOpcode::<wbr>G_ZEXT, Res, Op);<br>
+}<br>
<br>
- return buildInstr(Opcode).addDef(Res)<wbr>.addUse(Op);<br>
+MachineInstrBuilder MachineIRBuilder::<wbr>buildAnyExtOrTrunc(unsigned Res,<br>
+ unsigned Op) {<br>
+ return buildExtOrTrunc(TargetOpcode::<wbr>G_ANYEXT, Res, Op);<br>
}<br>
<br>
MachineInstrBuilder MachineIRBuilder::buildCast(<wbr>unsigned Dst, unsigned Src) {<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/<wbr>AArch64LegalizerInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp?rev=311763&r1=311762&r2=311763&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/Target/<wbr>AArch64/AArch64LegalizerInfo.<wbr>cpp?rev=311763&r1=311762&r2=<wbr>311763&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AArch64/<wbr>AArch64LegalizerInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/<wbr>AArch64LegalizerInfo.cpp Thu Aug 24 21:57:27 2017<br>
@@ -41,6 +41,9 @@ AArch64LegalizerInfo::<wbr>AArch64LegalizerIn<br>
for (auto Ty : {s16, s32, s64})<br>
setAction({G_PHI, Ty}, Legal);<br>
<br>
+ for (auto Ty : {s1, s8})<br>
+ setAction({G_PHI, Ty}, WidenScalar);<br>
+<br>
for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) {<br>
// These operations naturally get the right answer when used on<br>
// GPR32, even if the actual type is narrower.<br>
<br>
Added: llvm/trunk/test/CodeGen/<wbr>AArch64/GlobalISel/legalize-<wbr>phi.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-phi.mir?rev=311763&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>CodeGen/AArch64/GlobalISel/<wbr>legalize-phi.mir?rev=311763&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/<wbr>AArch64/GlobalISel/legalize-<wbr>phi.mir (added)<br>
+++ llvm/trunk/test/CodeGen/<wbr>AArch64/GlobalISel/legalize-<wbr>phi.mir Thu Aug 24 21:57:27 2017<br>
@@ -0,0 +1,433 @@<br>
+# RUN: llc -mtriple=aarch64-unknown-<wbr>unknown -global-isel -verify-machineinstrs -run-pass=legalizer %s -o - | FileCheck %s<br>
+--- |<br>
+ ; ModuleID = '/tmp/test.ll'<br>
+ source_filename = "/tmp/test.ll"<br>
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:<wbr>64-i128:128-n32:64-S128"<br>
+ target triple = "aarch64-unknown-unknown"<br>
+<br>
+ define i32 @legalize_phi(i32 %argc) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+<br>
+ define i32 @legalize_phi_empty(i32 %argc) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+<br>
+ define i32 @legalize_phi_loop(i32 %argc) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+<br>
+ define i32 @legalize_phi_cycle(i32 %argc) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+ define i32 @legalize_phi_same_bb(i32 %argc) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+<br>
+ define i32 @legalize_phi_diff_bb(i32 %argc, i32 %argc2) {<br>
+ entry:<br>
+ ret i32 0<br>
+ }<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+ - { id: 5, class: _, preferred-register: '' }<br>
+ - { id: 6, class: _, preferred-register: '' }<br>
+ - { id: 7, class: _, preferred-register: '' }<br>
+ - { id: 8, class: _, preferred-register: '' }<br>
+ - { id: 9, class: _, preferred-register: '' }<br>
+ - { id: 10, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ ; Test that we insert legalization artifacts(Truncs here) into the correct BBs<br>
+ ; while legalizing the G_PHI to s16.<br>
+ ; CHECK-LABEL: name: legalize_phi<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[ADD_BB1:%.*]](s32) = G_ADD<br>
+ ; CHECK: [[RES_BB1:%.*]](s16) = G_TRUNC [[ADD_BB1]]<br>
+<br>
+ ; CHECK-LABEL: bb.2:<br>
+ ; CHECK: [[ADD_BB2:%.*]](s32) = G_ADD<br>
+ ; CHECK: [[RES_BB2:%.*]](s16) = G_TRUNC [[ADD_BB2]]<br>
+<br>
+ ; CHECK-LABEL: bb.3:<br>
+ ; CHECK: [[RES_PHI:%.*]](s16) = G_PHI [[RES_BB1]](s16), %bb.1, [[RES_BB2]](s16), %bb.2<br>
+ ; CHECK: [[RES:%.*]](s1) = G_TRUNC [[RES_PHI]]<br>
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)<br>
+ liveins: %w0<br>
+<br>
+ %0(s32) = COPY %w0<br>
+ %1(s32) = G_CONSTANT i32 0<br>
+ %3(s32) = G_CONSTANT i32 1<br>
+ %6(s32) = G_CONSTANT i32 2<br>
+ %2(s1) = G_ICMP intpred(ugt), %0(s32), %1<br>
+ G_BRCOND %2(s1), %bb.1<br>
+ G_BR %bb.2<br>
+<br>
+ bb.1:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+ %4(s32) = G_ADD %0, %3<br>
+ %5(s1) = G_TRUNC %4(s32)<br>
+ G_BR %bb.3<br>
+<br>
+ bb.2:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+ %7(s32) = G_ADD %0, %6<br>
+ %8(s1) = G_TRUNC %7(s32)<br>
+<br>
+ bb.3:<br>
+ %9(s1) = G_PHI %5(s1), %bb.1, %8(s1), %bb.2<br>
+ %10(s32) = G_ZEXT %9(s1)<br>
+ %w0 = COPY %10(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi_empty<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+ - { id: 5, class: _, preferred-register: '' }<br>
+ - { id: 6, class: _, preferred-register: '' }<br>
+ - { id: 7, class: _, preferred-register: '' }<br>
+ - { id: 8, class: _, preferred-register: '' }<br>
+ - { id: 9, class: _, preferred-register: '' }<br>
+ - { id: 10, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)<br>
+ liveins: %w0<br>
+ ; Test that we properly legalize a phi with a predecessor that's empty<br>
+ ; CHECK-LABEL: name: legalize_phi_empty<br>
+ ; CHECK-LABEL: bb.0:<br>
+ ; CHECK: [[ENTRY_ADD:%.*]](s32) = G_ADD<br>
+<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[ADD_BB1:%.*]](s32) = G_ADD<br>
+ ; CHECK: [[RES_BB1:%.*]](s16) = G_TRUNC [[ADD_BB1]]<br>
+<br>
+ ; CHECK-LABEL: bb.2:<br>
+ ; CHECK: [[RES_BB2:%.*]](s16) = G_TRUNC [[ENTRY_ADD]]<br>
+<br>
+ ; CHECK: [[RES_PHI:%.*]](s16) = G_PHI [[RES_BB1]](s16), %bb.1, [[RES_BB2]](s16), %bb.2<br>
+ ; CHECK: [[RES:%.*]](s1) = G_TRUNC [[RES_PHI]]<br>
+<br>
+ %0(s32) = COPY %w0<br>
+ %1(s32) = G_CONSTANT i32 0<br>
+ %3(s32) = G_CONSTANT i32 3<br>
+ %6(s32) = G_CONSTANT i32 1<br>
+ %2(s1) = G_ICMP intpred(ugt), %0(s32), %1<br>
+ %4(s32) = G_ADD %0, %3<br>
+ %5(s1) = G_TRUNC %4(s32)<br>
+ G_BRCOND %2(s1), %bb.1<br>
+ G_BR %bb.2<br>
+<br>
+ bb.1:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+ %7(s32) = G_ADD %0, %6<br>
+ %8(s1) = G_TRUNC %7(s32)<br>
+ G_BR %bb.3<br>
+<br>
+ bb.2:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+<br>
+ bb.3:<br>
+ %9(s1) = G_PHI %8(s1), %bb.1, %5(s1), %bb.2<br>
+ %10(s32) = G_ZEXT %9(s1)<br>
+ %w0 = COPY %10(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi_loop<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+ - { id: 5, class: _, preferred-register: '' }<br>
+ - { id: 6, class: _, preferred-register: '' }<br>
+ - { id: 7, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ successors: %bb.1(0x80000000)<br>
+ liveins: %w0<br>
+ ; Test that we properly legalize a phi that uses a value from the same BB<br>
+ ; CHECK-LABEL: name: legalize_phi_loop<br>
+ ; CHECK-LABEL: bb.0:<br>
+ ; CHECK: [[C0:%.*]](s32) = G_CONSTANT i32 0<br>
+ ; CHECK: [[RES_BB1:%.*]](s16) = G_TRUNC [[C0]]<br>
+<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[RES_PHI:%.*]](s16) = G_PHI [[RES_BB1]](s16), %bb.0, [[RES_BB2:%.*]](s16), %bb.1<br>
+ ; CHECK-NEXT: G_TRUNC<br>
+ ; CHECK: [[RES_BB2]](s16) = G_ANYEXT<br>
+ %0(s32) = COPY %w0<br>
+ %2(s8) = G_CONSTANT i8 1<br>
+ %7(s8) = G_CONSTANT i8 0<br>
+<br>
+ bb.1:<br>
+ successors: %bb.1(0x40000000), %bb.3(0x40000000)<br>
+<br>
+ %1(s8) = G_PHI %7(s8), %bb.0, %3(s8), %bb.1<br>
+ %3(s8) = G_ADD %1, %2<br>
+ %4(s32) = G_ZEXT %3(s8)<br>
+ %5(s1) = G_ICMP intpred(ugt), %4(s32), %0<br>
+ G_BRCOND %5(s1), %bb.1<br>
+<br>
+ bb.3:<br>
+ %6(s32) = G_ZEXT %3(s8)<br>
+ %w0 = COPY %6(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi_cycle<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ successors: %bb.1(0x80000000)<br>
+ liveins: %w0<br>
+ ; Test that we properly legalize a phi that uses itself<br>
+ ; CHECK-LABEL: name: legalize_phi_cycle<br>
+ ; CHECK-LABEL: bb.0:<br>
+ ; CHECK: [[C0:%.*]](s32) = G_CONSTANT i32 0<br>
+ ; CHECK: [[RES_BB1:%.*]](s16) = G_TRUNC [[C0]]<br>
+<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[RES_PHI:%.*]](s16) = G_PHI [[RES_BB1]](s16), %bb.0, [[RES_BB2:%.*]](s16), %bb.1<br>
+ ; CHECK-NEXT: G_TRUNC<br>
+ ; CHECK: [[RES_BB2]](s16) = G_ANYEXT<br>
+<br>
+ %0(s32) = COPY %w0<br>
+ %4(s8) = G_CONSTANT i8 0<br>
+<br>
+ bb.1:<br>
+ successors: %bb.1(0x40000000), %bb.3(0x40000000)<br>
+<br>
+ %1(s8) = G_PHI %4(s8), %bb.0, %1(s8), %bb.1<br>
+ %2(s32) = G_ZEXT %1(s8)<br>
+ %3(s1) = G_ICMP intpred(ugt), %2(s32), %0<br>
+ G_BRCOND %3(s1), %bb.1<br>
+<br>
+ bb.3:<br>
+ %w0 = COPY %2(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi_same_bb<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+ - { id: 5, class: _, preferred-register: '' }<br>
+ - { id: 6, class: _, preferred-register: '' }<br>
+ - { id: 7, class: _, preferred-register: '' }<br>
+ - { id: 8, class: _, preferred-register: '' }<br>
+ - { id: 9, class: _, preferred-register: '' }<br>
+ - { id: 10, class: _, preferred-register: '' }<br>
+ - { id: 11, class: _, preferred-register: '' }<br>
+ - { id: 12, class: _, preferred-register: '' }<br>
+ - { id: 13, class: _, preferred-register: '' }<br>
+ - { id: 14, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ successors: %bb.1(0x40000000), %bb.2(0x40000000)<br>
+ liveins: %w0<br>
+ ; Make sure that we correctly insert the new legalized G_PHI at the<br>
+ ; correct location (ie make sure G_PHIs are the first insts in the BB).<br>
+ ; CHECK-LABEL: name: legalize_phi_same_bb<br>
+ ; CHECK-LABEL: bb.0:<br>
+ ; CHECK: [[C42:%.*]](s32) = G_CONSTANT i32 42<br>
+ ; CHECK: [[ENTRY_ADD:%.*]](s32) = G_ADD<br>
+<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[BB1_ADD:%.*]](s32) = G_ADD<br>
+ ; CHECK: [[RES1_BB1:%.*]](s16) = G_TRUNC [[BB1_ADD]]<br>
+ ; CHECK: [[RES2_BB1:%.*]](s16) = G_TRUNC [[BB1_ADD]]<br>
+<br>
+ ; CHECK-LABEL: bb.2:<br>
+ ; CHECK: [[RES1_BB2:%.*]](s16) = G_TRUNC [[ENTRY_ADD]]<br>
+ ; CHECK: [[RES2_BB2:%.*]](s16) = G_TRUNC [[C42]]<br>
+<br>
+ ; CHECK-LABEL: bb.3:<br>
+ ; CHECK: [[RES1_PHI:%.*]](s16) = G_PHI [[RES1_BB1]](s16), %bb.1, [[RES1_BB2]](s16), %bb.2<br>
+ ; CHECK-NEXT: [[RES_PHI:%.*]](s16) = G_PHI [[RES2_BB1]](s16), %bb.1, [[RES2_BB2]](s16), %bb.2<br>
+ ; CHECK-NEXT: G_TRUNC<br>
+ ; CHECK-NEXT: G_TRUNC<br>
+<br>
+ %0(s32) = COPY %w0<br>
+ %1(s32) = G_CONSTANT i32 0<br>
+ %3(s32) = G_CONSTANT i32 3<br>
+ %6(s32) = G_CONSTANT i32 1<br>
+ %14(s8) = G_CONSTANT i8 42<br>
+ %2(s1) = G_ICMP intpred(ugt), %0(s32), %1<br>
+ %4(s32) = G_ADD %0, %3<br>
+ %5(s8) = G_TRUNC %4(s32)<br>
+ G_BRCOND %2(s1), %bb.1<br>
+ G_BR %bb.2<br>
+<br>
+ bb.1:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+ %7(s32) = G_ADD %0, %6<br>
+ %8(s8) = G_TRUNC %7(s32)<br>
+ G_BR %bb.3<br>
+<br>
+ bb.2:<br>
+ successors: %bb.3(0x80000000)<br>
+<br>
+<br>
+ bb.3:<br>
+ %9(s8) = G_PHI %8(s8), %bb.1, %5(s8), %bb.2<br>
+ %10(s8) = G_PHI %8(s8), %bb.1, %14(s8), %bb.2<br>
+ %11(s32) = G_ZEXT %9(s8)<br>
+ %12(s32) = G_ZEXT %10(s8)<br>
+ %13(s32) = G_ADD %11, %12<br>
+ %w0 = COPY %13(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+---<br>
+name: legalize_phi_diff_bb<br>
+alignment: 2<br>
+exposesReturnsTwice: false<br>
+legalized: false<br>
+regBankSelected: false<br>
+selected: false<br>
+tracksRegLiveness: true<br>
+registers:<br>
+ - { id: 0, class: _, preferred-register: '' }<br>
+ - { id: 1, class: _, preferred-register: '' }<br>
+ - { id: 2, class: _, preferred-register: '' }<br>
+ - { id: 3, class: _, preferred-register: '' }<br>
+ - { id: 4, class: _, preferred-register: '' }<br>
+ - { id: 5, class: _, preferred-register: '' }<br>
+ - { id: 6, class: _, preferred-register: '' }<br>
+ - { id: 7, class: _, preferred-register: '' }<br>
+ - { id: 8, class: _, preferred-register: '' }<br>
+ - { id: 9, class: _, preferred-register: '' }<br>
+ - { id: 10, class: _, preferred-register: '' }<br>
+ - { id: 11, class: _, preferred-register: '' }<br>
+ - { id: 12, class: _, preferred-register: '' }<br>
+ - { id: 13, class: _, preferred-register: '' }<br>
+ - { id: 14, class: _, preferred-register: '' }<br>
+ - { id: 15, class: _, preferred-register: '' }<br>
+liveins:<br>
+body: |<br>
+ bb.0:<br>
+ successors: %bb.1(0x40000000), %bb.3(0x40000000)<br>
+ liveins: %w0, %w1<br>
+ ; Make sure that we correctly legalize PHIs sharing common defs<br>
+ ; in different BBs.<br>
+ ; CHECK-LABEL: name: legalize_phi_diff_bb<br>
+ ; CHECK-LABEL: bb.0:<br>
+ ; CHECK: [[C44:%.*]](s32) = G_CONSTANT i32 44<br>
+ ; CHECK: [[C43:%.*]](s32) = G_CONSTANT i32 43<br>
+ ; CHECK: [[ENTRY_ADD:%.*]](s32) = G_ADD<br>
+ ; CHECK: [[RES_ENTRY:%.*]](s16) = G_TRUNC [[ENTRY_ADD]]<br>
+ ; CHECK: [[RES_ENTRY1:%.*]](s16) = G_TRUNC [[ENTRY_ADD]]<br>
+<br>
+ ; CHECK-LABEL: bb.1:<br>
+ ; CHECK: [[RES1_PHI:%.*]](s16) = G_PHI [[RES_ENTRY]](s16), %bb.0, [[RES_BB1:%.*]](s16), %bb.1<br>
+ ; CHECK: [[RES_BB1:%.*]](s16) = G_TRUNC<br>
+ ; CHECK: [[RES_FOR_BB2:%.*]](s16) = COPY [[RES1_PHI]]<br>
+<br>
+ ; CHECK-LABEL: bb.2:<br>
+ ; CHECK: [[RES2_PHI:%.*]](s16) = G_PHI [[RES_FOR_BB2]](s16), %bb.1, [[RES_ENTRY1:%.*]](s16), %bb.0<br>
+ ; CHECK-NEXT: G_TRUNC<br>
+<br>
+ %0(s32) = COPY %w0<br>
+ %1(s32) = COPY %w1<br>
+ %2(s32) = G_CONSTANT i32 0<br>
+ %4(s32) = G_CONSTANT i32 3<br>
+ %9(s32) = G_CONSTANT i32 1<br>
+ %11(s32) = G_CONSTANT i32 44<br>
+ %15(s8) = G_CONSTANT i8 43<br>
+ %3(s1) = G_ICMP intpred(ugt), %0(s32), %2<br>
+ %5(s32) = G_ADD %0, %4<br>
+ %6(s8) = G_TRUNC %5(s32)<br>
+ G_BRCOND %3(s1), %bb.1<br>
+ G_BR %bb.3<br>
+<br>
+ bb.1:<br>
+ successors: %bb.3(0x40000000), %bb.1(0x40000000)<br>
+<br>
+ %7(s8) = G_PHI %6(s8), %bb.0, %15(s8), %bb.1<br>
+ %8(s32) = G_ZEXT %7(s8)<br>
+ %10(s32) = G_ADD %8, %9<br>
+ %12(s1) = G_ICMP intpred(ugt), %10(s32), %11<br>
+ G_BRCOND %12(s1), %bb.3<br>
+ G_BR %bb.1<br>
+<br>
+ bb.3:<br>
+ %13(s8) = G_PHI %7(s8), %bb.1, %6(s8), %bb.0<br>
+ %14(s32) = G_ZEXT %13(s8)<br>
+ %w0 = COPY %14(s32)<br>
+ RET_ReallyLR implicit %w0<br>
+<br>
+...<br>
+<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>