ARM: maintain BB ordering when expanding WIN__DBZCHK
authorSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 25 Mar 2016 19:48:06 +0000 (19:48 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Fri, 25 Mar 2016 19:48:06 +0000 (19:48 +0000)
It is possible to have a fallthrough MBB prior to MBB placement.  The original
addition of the BB would result in reordering the BB as not preceding the
successor.  Because of the fallthrough nature of the BB, we could end up
executing incorrect code or even a constant pool island!  Insert the spliced BB
into the same location to avoid that.

Thanks to Tim Northover for invaluable hints and Fiora for the discussion on
what may have been occurring!

llvm-svn: 264454

llvm/lib/Target/ARM/ARMISelLowering.cpp
llvm/test/CodeGen/ARM/Windows/dbzchk.ll
llvm/test/CodeGen/ARM/Windows/division.ll

index 0d9b77a..da72c25 100644 (file)
@@ -8051,7 +8051,7 @@ ARMTargetLowering::EmitLowered__dbzchk(MachineInstr *MI,
   const TargetInstrInfo *TII = Subtarget->getInstrInfo();
 
   MachineBasicBlock *ContBB = MF->CreateMachineBasicBlock();
-  MF->push_back(ContBB);
+  MF->insert(++MBB->getIterator(), ContBB);
   ContBB->splice(ContBB->begin(), MBB,
                  std::next(MachineBasicBlock::iterator(MI)), MBB->end());
   ContBB->transferSuccessorsAndUpdatePHIs(MBB);
index 341d390..487464c 100644 (file)
@@ -78,3 +78,67 @@ return:
 ; CHECK-MOD-DAG: Successors according to CFG: BB#2
 ; CHECK-MOD-DAG: BB#4
 
+; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -filetype asm -o - %s 2>&1 | FileCheck %s -check-prefix CHECK-CFG
+
+; unsigned c;
+; extern unsigned long g(void);
+; int f(unsigned u, signed char b) {
+;   if (b)
+;     c = g() % u;
+;   return c;
+; }
+
+@c = common global i32 0, align 4
+
+declare arm_aapcs_vfpcc i32 @i()
+
+define arm_aapcs_vfpcc i32 @h(i32 %u, i8 signext %b) #0 {
+entry:
+  %tobool = icmp eq i8 %b, 0
+  br i1 %tobool, label %entry.if.end_crit_edge, label %if.then
+
+entry.if.end_crit_edge:
+  %.pre = load i32, i32* @c, align 4
+  br label %if.end
+
+if.then:
+  %call = tail call arm_aapcs_vfpcc i32 @i()
+  %rem = urem i32 %call, %u
+  store i32 %rem, i32* @c, align 4
+  br label %if.end
+
+if.end:
+  %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %rem, %if.then ]
+  ret i32 %0
+}
+
+attributes #0 = { optsize }
+
+; CHECK-CFG-DAG: BB#0
+; CHECK-CFG_DAG: t2Bcc <BB#2>
+; CHECK-CFG-DAG: t2B <BB#1>
+
+; CHECK-CFG-DAG: BB#1
+; CHECK-CFG-DAG: t2B <BB#3>
+
+; CHECK-CFG-DAG: BB#2
+; CHECK-CFG-DAG: tCBZ %vreg{{[0-9]}}, <BB#5>
+; CHECK-CFG-DAG: t2B <BB#4>
+
+; CHECK-CFG-DAG: BB#4
+
+; CHECK-CFG-DAG: BB#3
+; CHECK-CFG-DAG: tBX_RET
+
+; CHECK-CFG-DAG: BB#5
+; CHECK-CFG-DAG: t2UDF 249
+
+; CHECK-CFG-LABEL: h:
+; CHECK-CFG: cbz r{{[0-9]}}, .LBB2_2
+; CHECK-CFG: b .LBB2_4
+; CHECK-CFG-LABEL: .LBB2_2:
+; CHECK-CFG-NEXT: udf.w #249
+; CHECK-CFG-LABEL: .LBB2_4:
+; CHECK-CFG: bl __rt_udiv
+; CHECK-CFG: pop.w {{{.*}}, r11, pc}
+
index a3d467f..35dfe1b 100644 (file)
@@ -51,28 +51,3 @@ entry:
 ; CHECK: udf.w #249
 ; CHECK: bl __rt_udiv64
 
-declare arm_aapcs_vfpcc i32 @g(...)
-
-define arm_aapcs_vfpcc i32 @f(i32 %b, i32 %d) #0 {
-entry:
-  %tobool = icmp eq i32 %b, 0
-  br i1 %tobool, label %return, label %if.then
-
-if.then:
-  %call = tail call arm_aapcs_vfpcc i32 bitcast (i32 (...)* @g to i32 ()*)()
-  %rem = urem i32 %call, %d
-  br label %return
-
-return:
-  %retval.0 = phi i32 [ %rem, %if.then ], [ 0, %entry ]
-  ret i32 %retval.0
-}
-
-; CHECK-LABEL: f:
-; CHECK: cbz r0,
-; CHECK: cbz r4,
-; CHECK: b
-; CHECK: udf.w #249
-
-attributes #0 = { optsize }
-