llvm.org GIT mirror llvm / b95f965
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343731 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 1 year, 9 months ago
2 changed file(s) with 95 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
108108 using RegMap = DenseMap;
109109 using BlockSet = SmallPtrSet;
110110
111 const MachineInstr *FirstNonPHI;
111112 const MachineInstr *FirstTerminator;
112113 BlockSet FunctionBlocks;
113114
607608 void
608609 MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
609610 FirstTerminator = nullptr;
611 FirstNonPHI = nullptr;
610612
611613 if (!MF->getProperties().hasProperty(
612614 MachineFunctionProperties::Property::NoPHIs) && MRI->tracksLiveness()) {
888890 << MI->getNumOperands() << " given.\n";
889891 }
890892
891 if (MI->isPHI() && MF->getProperties().hasProperty(
892 MachineFunctionProperties::Property::NoPHIs))
893 report("Found PHI instruction with NoPHIs property set", MI);
893 if (MI->isPHI()) {
894 if (MF->getProperties().hasProperty(
895 MachineFunctionProperties::Property::NoPHIs))
896 report("Found PHI instruction with NoPHIs property set", MI);
897
898 if (FirstNonPHI)
899 report("Found PHI instruction after non-PHI", MI);
900 } else if (FirstNonPHI == nullptr)
901 FirstNonPHI = MI;
894902
895903 // Check the tied operands.
896904 if (MI->isInlineAsm())
0 # RUN: not llc -run-pass=machineverifier %s -o - 2>&1 | FileCheck %s
1 # REQUIRES: aarch64-registered-target
2
3 --- |
4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5 target triple = "aarch64--"
6 define void @valid(i8* %addr) {
7 entry:
8 br i1 0, label %if, label %else
9 if:
10 br label %exit
11 else:
12 br label %exit
13 exit:
14 ret void
15 }
16
17 define void @broken(i8* %addr) {
18 entry:
19 br i1 0, label %if, label %exit
20 if:
21 br label %exit
22 exit:
23 ret void
24 }
25 ...
26
27 ---
28 name: valid
29 tracksRegLiveness: true
30 body: |
31 bb.0.entry:
32 liveins: $w1
33 successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%)
34 %1:_(s32) = COPY $w1
35 %2:_(s32) = G_CONSTANT i32 1
36 %3:_(s1) = G_ICMP intpred(ne), %1:_(s32), %2:_
37 G_BRCOND %3:_(s1), %bb.1
38 G_BR %bb.2.else
39 bb.1.if:
40 successors: %bb.3(0x80000000)
41 %4:_(s32) = G_CONSTANT i32 1
42 %5:_(s8) = G_TRUNC %4
43 G_BR %bb.3.exit
44 bb.2.else:
45 successors: %bb.3(0x80000000)
46 %6:_(s32) = G_CONSTANT i8 1
47 %7:_(s8) = G_TRUNC %6
48 G_BR %bb.3.exit
49 bb.3.exit:
50 %8:_(s8) = G_PHI %5:_(s8), %bb.1, %7:_(s8), %bb.2
51 %9:_(s32) = G_ZEXT %8
52 $w1 = COPY %9
53 ...
54
55 ---
56 name: broken
57 tracksRegLiveness: true
58 body: |
59 bb.0.entry:
60 liveins: $w1
61 successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%)
62 %1:_(s32) = COPY $w1
63 %2:_(s32) = G_CONSTANT i32 1
64 %3:_(s1) = G_ICMP intpred(ne), %1:_(s32), %2:_
65 %4:_(s32) = G_CONSTANT i32 1
66 %6:_(s8) = G_CONSTANT i8 2
67 G_BRCOND %3:_(s1), %bb.1
68 G_BR %bb.2.exit
69 bb.1.if:
70 successors: %bb.2(0x80000000)
71 G_BR %bb.2.exit
72 bb.2.exit:
73 %5:_(s8) = G_TRUNC %4
74 %8:_(s8) = G_PHI %5:_(s8), %bb.0, %6:_(s8), %bb.1
75 %9:_(s32) = G_ZEXT %8
76 $w1 = COPY %9
77 ...
78 # CHECK-NOT: Bad machine code
79 # CHECK-LABEL: Bad machine code: Found PHI instruction after non-PHI
80 # CHECK-NEXT: - function: broken
81 # CHECK-NEXT: - basic block: %bb.2 exit
82 # CHECK-NEXT: - instruction: %6:_(s8) = G_PHI %5:_(s8), %bb.0, %4:_(s8), %bb.1
83 # CHECK-NOT: Bad machine code