]> granicus.if.org Git - llvm/commitdiff
GlobalISel: stop localizer putting constants before EH_LABELs
authorTim Northover <tnorthover@apple.com>
Thu, 20 Jul 2017 22:58:26 +0000 (22:58 +0000)
committerTim Northover <tnorthover@apple.com>
Thu, 20 Jul 2017 22:58:26 +0000 (22:58 +0000)
If the localizer pass puts one of its constants before the label that tells the
unwinder "jump here to handle your exception" then control-flow will skip it,
leaving uninitialized registers at runtime. That's bad.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308687 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GlobalISel/Localizer.cpp
test/CodeGen/AArch64/GlobalISel/localizer.mir

index c5d0999fe43889c6839dc0fa7945cb9c9e7f88eb..8cc44c505cbf05788629410dd8d56be79c9abd74 100644 (file)
@@ -101,7 +101,8 @@ bool Localizer::runOnMachineFunction(MachineFunction &MF) {
           // Don't try to be smart for the insertion point.
           // There is no guarantee that the first seen use is the first
           // use in the block.
-          InsertMBB->insert(InsertMBB->getFirstNonPHI(), LocalizedMI);
+          InsertMBB->insert(InsertMBB->SkipPHIsAndLabels(InsertMBB->begin()),
+                            LocalizedMI);
 
           // Set a new register for the definition.
           unsigned NewReg =
index afe2c13f025da4ab4897fa635e23d14c96de3f05..6a009520e1a8c554514522812ac5cf634bae8894 100644 (file)
@@ -13,6 +13,7 @@
   define void @non_local_phi_use_followed_by_use_fi() { ret void }
   define void @float_non_local_phi_use_followed_by_use_fi() { ret void }
   define void @non_local_phi() { ret void }
+  define void @non_local_label() { ret void }
 ...
 
 ---
@@ -359,3 +360,50 @@ body:             |
     %2(s32) = G_FADD %3, %1
     G_BR %bb.1
 ...
+
+---
+# Make sure we don't insert a constant before EH_LABELs.
+# CHECK-LABEL: name: non_local_label
+name:            non_local_label
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+
+# CHECK:      registers:
+# Existing registers should be left untouched
+# CHECK:  - { id: 0, class: fpr, preferred-register: '' }
+#CHECK-NEXT:  - { id: 1, class: fpr, preferred-register: '' }
+#CHECK-NEXT:  - { id: 2, class: fpr, preferred-register: '' }
+#CHECK-NEXT:  - { id: 3, class: fpr, preferred-register: '' }
+# The newly created reg should be on the same regbank/regclass as its origin.
+#CHECK-NEXT:  - { id: 4, class: fpr, preferred-register: '' }
+
+registers:
+  - { id: 0, class: fpr }
+  - { id: 1, class: fpr }
+  - { id: 2, class: fpr }
+  - { id: 3, class: fpr }
+
+# CHECK:  body:
+# CHECK:    %1(s32) = G_FCONSTANT float 1.0
+
+# CHECK: bb.1:
+# CHECK: EH_LABEL
+# CHECK: %4(s32) = G_FCONSTANT float 1.0
+
+# CHECK-NEXT: %2(s32) = G_FADD %0, %4
+body:             |
+  bb.0:
+    liveins: %s0
+    successors: %bb.1
+
+    %0(s32) = COPY %s0
+    %1(s32) = G_FCONSTANT float 1.0
+
+  bb.1:
+    successors: %bb.1
+
+    EH_LABEL 1
+    %2(s32) = G_FADD %0, %1
+    G_BR %bb.1
+...