From 8c0f7d831401a17fb1f706580ad38cb290c6170b Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 3 Oct 2018 22:05:31 +0000 Subject: [PATCH] [machineverifier] Detect PHI's that are preceeded by non-PHI's If present, PHI nodes must appear before non-PHI nodes in a basic block. The register allocator relies on this and will fail to eliminate PHI's that do not meet this requirement. llvm-svn: 343731 --- lib/CodeGen/MachineVerifier.cpp | 14 +++- test/Verifier/test_phis_precede_nonphis.mir | 84 +++++++++++++++++++++ 2 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 test/Verifier/test_phis_precede_nonphis.mir diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index e8de966b5e1..a19c2ef8002 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -109,6 +109,7 @@ namespace { using RegMap = DenseMap; using BlockSet = SmallPtrSet; + const MachineInstr *FirstNonPHI; const MachineInstr *FirstTerminator; BlockSet FunctionBlocks; @@ -608,6 +609,7 @@ static bool matchPair(MachineBasicBlock::const_succ_iterator i, void MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { FirstTerminator = nullptr; + FirstNonPHI = nullptr; if (!MF->getProperties().hasProperty( MachineFunctionProperties::Property::NoPHIs) && MRI->tracksLiveness()) { @@ -889,9 +891,15 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { << MI->getNumOperands() << " given.\n"; } - if (MI->isPHI() && MF->getProperties().hasProperty( - MachineFunctionProperties::Property::NoPHIs)) - report("Found PHI instruction with NoPHIs property set", MI); + if (MI->isPHI()) { + if (MF->getProperties().hasProperty( + MachineFunctionProperties::Property::NoPHIs)) + report("Found PHI instruction with NoPHIs property set", MI); + + if (FirstNonPHI) + report("Found PHI instruction after non-PHI", MI); + } else if (FirstNonPHI == nullptr) + FirstNonPHI = MI; // Check the tied operands. if (MI->isInlineAsm()) diff --git a/test/Verifier/test_phis_precede_nonphis.mir b/test/Verifier/test_phis_precede_nonphis.mir new file mode 100644 index 00000000000..29409798d1b --- /dev/null +++ b/test/Verifier/test_phis_precede_nonphis.mir @@ -0,0 +1,84 @@ +# RUN: not llc -run-pass=machineverifier %s -o - 2>&1 | FileCheck %s +# REQUIRES: aarch64-registered-target + +--- | + target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + target triple = "aarch64--" + define void @valid(i8* %addr) { + entry: + br i1 0, label %if, label %else + if: + br label %exit + else: + br label %exit + exit: + ret void + } + + define void @broken(i8* %addr) { + entry: + br i1 0, label %if, label %exit + if: + br label %exit + exit: + ret void + } +... + +--- +name: valid +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $w1 + successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%) + %1:_(s32) = COPY $w1 + %2:_(s32) = G_CONSTANT i32 1 + %3:_(s1) = G_ICMP intpred(ne), %1:_(s32), %2:_ + G_BRCOND %3:_(s1), %bb.1 + G_BR %bb.2.else + bb.1.if: + successors: %bb.3(0x80000000) + %4:_(s32) = G_CONSTANT i32 1 + %5:_(s8) = G_TRUNC %4 + G_BR %bb.3.exit + bb.2.else: + successors: %bb.3(0x80000000) + %6:_(s32) = G_CONSTANT i8 1 + %7:_(s8) = G_TRUNC %6 + G_BR %bb.3.exit + bb.3.exit: + %8:_(s8) = G_PHI %5:_(s8), %bb.1, %7:_(s8), %bb.2 + %9:_(s32) = G_ZEXT %8 + $w1 = COPY %9 +... + +--- +name: broken +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $w1 + successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%) + %1:_(s32) = COPY $w1 + %2:_(s32) = G_CONSTANT i32 1 + %3:_(s1) = G_ICMP intpred(ne), %1:_(s32), %2:_ + %4:_(s32) = G_CONSTANT i32 1 + %6:_(s8) = G_CONSTANT i8 2 + G_BRCOND %3:_(s1), %bb.1 + G_BR %bb.2.exit + bb.1.if: + successors: %bb.2(0x80000000) + G_BR %bb.2.exit + bb.2.exit: + %5:_(s8) = G_TRUNC %4 + %8:_(s8) = G_PHI %5:_(s8), %bb.0, %6:_(s8), %bb.1 + %9:_(s32) = G_ZEXT %8 + $w1 = COPY %9 +... +# CHECK-NOT: Bad machine code +# CHECK-LABEL: Bad machine code: Found PHI instruction after non-PHI +# CHECK-NEXT: - function: broken +# CHECK-NEXT: - basic block: %bb.2 exit +# CHECK-NEXT: - instruction: %6:_(s8) = G_PHI %5:_(s8), %bb.0, %4:_(s8), %bb.1 +# CHECK-NOT: Bad machine code