[llvm] r311596 - [GISEl]: Translate phi into G_PHI

Aditya Nandakumar via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 23 13:45:48 PDT 2017


Author: aditya_nandakumar
Date: Wed Aug 23 13:45:48 2017
New Revision: 311596

URL: http://llvm.org/viewvc/llvm-project?rev=311596&view=rev
Log:
[GISEl]: Translate phi into G_PHI

G_PHI has the same semantics as PHI but also has types.
This lets us verify that the types in the G_PHI are consistent.
This also allows specifying legalization actions for G_PHIs.

https://reviews.llvm.org/D36990

Added:
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-phi.mir
    llvm/trunk/test/Verifier/test_g_phi.mir
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineInstr.h
    llvm/trunk/include/llvm/Target/GenericOpcodes.td
    llvm/trunk/include/llvm/Target/TargetOpcodes.def
    llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
    llvm/trunk/lib/CodeGen/MachineVerifier.cpp
    llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
    llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
    llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll

Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Wed Aug 23 13:45:48 2017
@@ -792,7 +792,10 @@ public:
       && getOperand(1).isImm();
   }
 
-  bool isPHI() const { return getOpcode() == TargetOpcode::PHI; }
+  bool isPHI() const {
+    return getOpcode() == TargetOpcode::PHI ||
+           getOpcode() == TargetOpcode::G_PHI;
+  }
   bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
   bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
   bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
@@ -869,6 +872,7 @@ public:
       return isMetaInstruction();
     // Copy-like instructions are usually eliminated during register allocation.
     case TargetOpcode::PHI:
+    case TargetOpcode::G_PHI:
     case TargetOpcode::COPY:
     case TargetOpcode::INSERT_SUBREG:
     case TargetOpcode::SUBREG_TO_REG:

Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Wed Aug 23 13:45:48 2017
@@ -55,6 +55,12 @@ def G_IMPLICIT_DEF : Instruction {
   let hasSideEffects = 0;
 }
 
+def G_PHI : Instruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins variable_ops);
+  let hasSideEffects = 0;
+}
+
 def G_FRAME_INDEX : Instruction {
   let OutOperandList = (outs type0:$dst);
   let InOperandList = (ins unknown:$src2);

Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Wed Aug 23 13:45:48 2017
@@ -224,6 +224,9 @@ HANDLE_TARGET_OPCODE(G_XOR)
 
 HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)
 
+/// Generic PHI instruction with types.
+HANDLE_TARGET_OPCODE(G_PHI)
+
 /// Generic instruction to materialize the address of an alloca or other
 /// stack-based object.
 HANDLE_TARGET_OPCODE(G_FRAME_INDEX)

Modified: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp Wed Aug 23 13:45:48 2017
@@ -1098,7 +1098,7 @@ bool IRTranslator::translateShuffleVecto
 
 bool IRTranslator::translatePHI(const User &U, MachineIRBuilder &MIRBuilder) {
   const PHINode &PI = cast<PHINode>(U);
-  auto MIB = MIRBuilder.buildInstr(TargetOpcode::PHI);
+  auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI);
   MIB.addDef(getOrCreateVReg(PI));
 
   PendingPHIs.emplace_back(&PI, MIB.getInstr());

Modified: llvm/trunk/lib/CodeGen/MachineVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineVerifier.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineVerifier.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineVerifier.cpp Wed Aug 23 13:45:48 2017
@@ -926,6 +926,23 @@ void MachineVerifier::visitMachineInstrB
       report("Generic instruction accessing memory must have one mem operand",
              MI);
     break;
+  case TargetOpcode::G_PHI: {
+    LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+    if (!DstTy.isValid() ||
+        !std::all_of(MI->operands_begin() + 1, MI->operands_end(),
+                     [this, &DstTy](const MachineOperand &MO) {
+                       if (!MO.isReg())
+                         return true;
+                       LLT Ty = MRI->getType(MO.getReg());
+                       if (!Ty.isValid() || (Ty != DstTy))
+                         return false;
+                       return true;
+                     }))
+      report("Generic Instruction G_PHI has operands with incompatible/missing "
+             "types",
+             MI);
+    break;
+  }
   case TargetOpcode::STATEPOINT:
     if (!MI->getOperand(StatepointOpers::IDPos).isImm() ||
         !MI->getOperand(StatepointOpers::NBytesPos).isImm() ||

Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Wed Aug 23 13:45:48 2017
@@ -590,13 +590,14 @@ bool AArch64InstructionSelector::select(
   MachineRegisterInfo &MRI = MF.getRegInfo();
 
   unsigned Opcode = I.getOpcode();
-  if (!isPreISelGenericOpcode(I.getOpcode())) {
+  // G_PHI requires same handling as PHI
+  if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) {
     // Certain non-generic instructions also need some special handling.
 
     if (Opcode ==  TargetOpcode::LOAD_STACK_GUARD)
       return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
 
-    if (Opcode == TargetOpcode::PHI) {
+    if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) {
       const unsigned DefReg = I.getOperand(0).getReg();
       const LLT DefTy = MRI.getType(DefReg);
 
@@ -621,6 +622,7 @@ bool AArch64InstructionSelector::select(
           }
         }
       }
+      I.setDesc(TII.get(TargetOpcode::PHI));
 
       return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
     }

Modified: llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64LegalizerInfo.cpp Wed Aug 23 13:45:48 2017
@@ -38,6 +38,9 @@ AArch64LegalizerInfo::AArch64LegalizerIn
   for (auto Ty : {p0, s1, s8, s16, s32, s64})
     setAction({G_IMPLICIT_DEF, Ty}, Legal);
 
+  for (auto Ty : {s16, s32, s64})
+    setAction({G_PHI, Ty}, Legal);
+
   for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) {
     // These operations naturally get the right answer when used on
     // GPR32, even if the actual type is narrower.

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp Wed Aug 23 13:45:48 2017
@@ -420,7 +420,8 @@ AArch64RegisterBankInfo::getInstrMapping
 
   // Try the default logic for non-generic instructions that are either copies
   // or already have some operands assigned to banks.
-  if (!isPreISelGenericOpcode(Opc)) {
+  if (!isPreISelGenericOpcode(Opc) ||
+      Opc == TargetOpcode::G_PHI) {
     const RegisterBankInfo::InstructionMapping &Mapping =
         getInstrMappingImpl(MI);
     if (Mapping.isValid())

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterBankInfo.cpp Wed Aug 23 13:45:48 2017
@@ -198,7 +198,7 @@ ARMRegisterBankInfo::getInstrMapping(con
 
   // Try the default logic for non-generic instructions that are either copies
   // or already have some operands assigned to banks.
-  if (!isPreISelGenericOpcode(Opc)) {
+  if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
     if (Mapping.isValid())
       return Mapping;

Modified: llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterBankInfo.cpp Wed Aug 23 13:45:48 2017
@@ -160,7 +160,7 @@ X86RegisterBankInfo::getInstrMapping(con
 
   // Try the default logic for non-generic instructions that are either copies
   // or already have some operands assigned to banks.
-  if (!isPreISelGenericOpcode(Opc)) {
+  if (!isPreISelGenericOpcode(Opc) || Opc == TargetOpcode::G_PHI) {
     const InstructionMapping &Mapping = getInstrMappingImpl(MI);
     if (Mapping.isValid())
       return Mapping;

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll?rev=311596&r1=311595&r2=311596&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll Wed Aug 23 13:45:48 2017
@@ -170,7 +170,7 @@ false:
 ; CHECK: %[[regretc200:[0-9]+]](s32) = G_ADD %0, %[[reg2]]
 ;
 ; CHECK: [[BB_RET]]:
-; CHECK-NEXT: %[[regret:[0-9]+]](s32) = PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
+; CHECK-NEXT: %[[regret:[0-9]+]](s32) = G_PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
 ; CHECK:  %w0 = COPY %[[regret]](s32)
 ; CHECK:  RET_ReallyLR implicit %w0
 ;
@@ -211,7 +211,7 @@ return:
 ; CHECK: G_BR %[[PHI_BLOCK]]
 ;
 ; CHECK: [[PHI_BLOCK]]:
-; CHECK-NEXT: PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+.entry]], %{{.*}}(s32),
+; CHECK-NEXT: G_PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+.entry]], %{{.*}}(s32),
 ;
 define i32 @test_cfg_remap(i32 %in) {
 entry:
@@ -230,7 +230,7 @@ phi.block:
 }
 
 ; CHECK-LABEL: name: test_cfg_remap_multiple_preds
-; CHECK: PHI [[ENTRY:%.*]](s32), %bb.{{[0-9]+}}.entry, [[ENTRY]](s32), %bb.{{[0-9]+}}.entry
+; CHECK: G_PHI [[ENTRY:%.*]](s32), %bb.{{[0-9]+}}.entry, [[ENTRY]](s32), %bb.{{[0-9]+}}.entry
 define i32 @test_cfg_remap_multiple_preds(i32 %in) {
 entry:
   switch i32 %in, label %odd [i32 1, label %next
@@ -521,7 +521,7 @@ define void @intrinsics(i32 %cur, i32 %b
 ; CHECK: [[FALSE]]:
 ; CHECK:     [[RES2:%[0-9]+]](s32) = G_LOAD
 
-; CHECK:     [[RES:%[0-9]+]](s32) = PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
+; CHECK:     [[RES:%[0-9]+]](s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
 ; CHECK:     %w0 = COPY [[RES]]
 define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
   br i1 %tst, label %true, label %false

Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-phi.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-phi.mir?rev=311596&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-phi.mir (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/select-phi.mir Wed Aug 23 13:45:48 2017
@@ -0,0 +1,78 @@
+# RUN: llc -mtriple=aarch64-unknown-unknown -o - -global-isel -verify-machineinstrs -run-pass=instruction-select %s | FileCheck %s
+--- |
+  ; ModuleID = '/tmp/test.ll'
+  source_filename = "/tmp/test.ll"
+  target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+  target triple = "aarch64-unknown-unknown"
+  
+  define i32 @test_phi(i32 %argc) {
+  entry:
+    %cmp = icmp ugt i32 %argc, 0
+    br i1 %cmp, label %case1, label %case2
+  
+  case1:                                            ; preds = %entry
+    %tmp1 = add i32 %argc, 1
+    br label %return
+  
+  case2:                                            ; preds = %entry
+    %tmp2 = add i32 %argc, 2
+    br label %return
+  
+  return:                                           ; preds = %case2, %case1
+    %res = phi i32 [ %tmp1, %case1 ], [ %tmp2, %case2 ]
+    ret i32 %res
+  }
+
+...
+---
+name:            test_phi
+alignment:       2
+exposesReturnsTwice: false
+legalized:       true
+regBankSelected: true
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: gpr, preferred-register: '' }
+  - { id: 1, class: gpr, preferred-register: '' }
+  - { id: 2, class: gpr, preferred-register: '' }
+  - { id: 3, class: gpr, preferred-register: '' }
+  - { id: 4, class: gpr, preferred-register: '' }
+  - { id: 5, class: gpr, preferred-register: '' }
+  - { id: 6, class: gpr, preferred-register: '' }
+  - { id: 7, class: gpr, preferred-register: '' }
+  - { id: 8, class: gpr, preferred-register: '' }
+liveins:         
+body:             |
+  bb.1.entry:
+    successors: %bb.2.case1(0x40000000), %bb.3.case2(0x40000000)
+    liveins: %w0
+    ; CHECK-LABEL: name: test_phi
+    ; CHECK: [[RES:%.*]] = PHI
+  
+    %0(s32) = COPY %w0
+    %1(s32) = G_CONSTANT i32 0
+    %3(s32) = G_CONSTANT i32 1
+    %5(s32) = G_CONSTANT i32 2
+    %8(s32) = G_ICMP intpred(ugt), %0(s32), %1
+    %2(s1) = G_TRUNC %8(s32)
+    G_BRCOND %2(s1), %bb.2.case1
+    G_BR %bb.3.case2
+  
+  bb.2.case1:
+    successors: %bb.4.return(0x80000000)
+  
+    %4(s32) = G_ADD %0, %3
+    G_BR %bb.4.return
+  
+  bb.3.case2:
+    successors: %bb.4.return(0x80000000)
+  
+    %6(s32) = G_ADD %0, %5
+  
+  bb.4.return:
+    %7(s32) = G_PHI %4(s32), %bb.2.case1, %6(s32), %bb.3.case2
+    %w0 = COPY %7(s32)
+    RET_ReallyLR implicit %w0
+
+...

Added: llvm/trunk/test/Verifier/test_g_phi.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Verifier/test_g_phi.mir?rev=311596&view=auto
==============================================================================
--- llvm/trunk/test/Verifier/test_g_phi.mir (added)
+++ llvm/trunk/test/Verifier/test_g_phi.mir Wed Aug 23 13:45:48 2017
@@ -0,0 +1,78 @@
+#RUN: not llc -mtriple=aarch64-unknown-unknown -o - -global-isel -run-pass=legalizer -verify-machineinstrs %s 2>&1 | FileCheck %s
+--- |
+  ; ModuleID = 'test.ll'
+  source_filename = "test.ll"
+  target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+  target triple = "aarch64-unknown-unknown"
+  
+  define i32 @test_phi(i32 %argc) {
+  entry:
+    %cmp = icmp ugt i32 %argc, 0
+    br i1 %cmp, label %case1, label %case2
+  
+  case1:                                            ; preds = %entry
+    %tmp11 = add i32 %argc, 1
+    br label %return
+  
+  case2:                                            ; preds = %entry
+    %tmp22 = add i32 %argc, 2
+    br label %return
+  
+  return:                                           ; preds = %case2, %case1
+    %res = phi i32 [ %tmp11, %case1 ], [ %tmp22, %case2 ]
+    ret i32 %res
+  }
+
+...
+---
+name:            test_phi
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: _, preferred-register: '' }
+  - { id: 1, class: _, preferred-register: '' }
+  - { id: 2, class: _, preferred-register: '' }
+  - { id: 3, class: _, preferred-register: '' }
+  - { id: 4, class: _, preferred-register: '' }
+  - { id: 5, class: _, preferred-register: '' }
+  - { id: 6, class: _, preferred-register: '' }
+  - { id: 7, class: _, preferred-register: '' }
+  - { id: 8, class: _, preferred-register: '' }
+  - { id: 9, class: _, preferred-register: '' }
+liveins:         
+body:             |
+  bb.1.entry:
+    successors: %bb.2.case1(0x40000000), %bb.3.case2(0x40000000)
+    liveins: %w0
+    ; This test makes sure that the Verifier catches G_PHI with mismatching types.
+    ; CHECK: Bad machine code: Generic Instruction G_PHI has operands with incompatible/missing types
+  
+    %0(s32) = COPY %w0
+    %1(s32) = G_CONSTANT i32 0
+    %3(s32) = G_CONSTANT i32 1
+    %5(s32) = G_CONSTANT i32 2
+    %8(s32) = G_ICMP intpred(ugt), %0(s32), %1
+    %2(s1) = G_TRUNC %8(s32)
+    G_BRCOND %2(s1), %bb.2.case1
+    G_BR %bb.3.case2
+  
+  bb.2.case1:
+    successors: %bb.4.return(0x80000000)
+  
+    %4(s32) = G_ADD %0, %3
+    %9(s16) = G_TRUNC %4(s32)
+    G_BR %bb.4.return
+  
+  bb.3.case2:
+    successors: %bb.4.return(0x80000000)
+  
+    %6(s32) = G_ADD %0, %5
+  
+  bb.4.return:
+    %7(s32) = G_PHI %9(s16), %bb.2.case1, %6(s32), %bb.3.case2
+    %w0 = COPY %7(s32)
+    RET_ReallyLR implicit %w0
+
+...




More information about the llvm-commits mailing list