Branches must be the last instruction in a Thumb2 IT block. Approved by Evan Cheng.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84212 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sandeep Patel 2009-10-15 22:25:32 +00:00
parent 6f122625dd
commit 452b54a8ae
2 changed files with 49 additions and 1 deletions

View File

@ -107,8 +107,12 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) {
// Finalize IT mask.
ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
unsigned Mask = 0, Pos = 3;
while (MBBI != E && Pos) {
// Branches, including tricky ones like LDM_RET, need to end an IT
// block so check the instruction we just put in the block.
while (MBBI != E && Pos &&
(!MI->getDesc().isBranch() && !MI->getDesc().isReturn())) {
MachineInstr *NMI = &*MBBI;
MI = NMI;
DebugLoc ndl = NMI->getDebugLoc();
unsigned NPredReg = 0;
ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg);

View File

@ -0,0 +1,44 @@
; RUN: llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 -float-abi=hard | FileCheck %s
; A fix for PR5204 will require this check to be changed.
%"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* }
%"struct.__gnu_cxx::new_allocator<char>" = type <{ i8 }>
%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" }
%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" }
%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" = type { i32, i32, i32 }
define weak arm_aapcs_vfpcc i32 @_ZNKSs7compareERKSs(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) {
; CHECK: _ZNKSs7compareERKSs:
; CHECK: it ne
; CHECK-NEXT: ldmfdne.w
; CHECK-NEXT: itt eq
; CHECK-NEXT: subeq.w
; CHECK-NEXT: ldmfdeq.w
entry:
%0 = tail call arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) ; <i32> [#uses=3]
%1 = tail call arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) ; <i32> [#uses=3]
%2 = icmp ult i32 %1, %0 ; <i1> [#uses=1]
%3 = select i1 %2, i32 %1, i32 %0 ; <i32> [#uses=1]
%4 = tail call arm_aapcs_vfpcc i8* @_ZNKSs7_M_dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) ; <i8*> [#uses=1]
%5 = tail call arm_aapcs_vfpcc i8* @_ZNKSs4dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) ; <i8*> [#uses=1]
%6 = tail call arm_aapcs_vfpcc i32 @memcmp(i8* %4, i8* %5, i32 %3) nounwind readonly ; <i32> [#uses=2]
%7 = icmp eq i32 %6, 0 ; <i1> [#uses=1]
br i1 %7, label %bb, label %bb1
bb: ; preds = %entry
%8 = sub i32 %0, %1 ; <i32> [#uses=1]
ret i32 %8
bb1: ; preds = %entry
ret i32 %6
}
declare arm_aapcs_vfpcc i32 @memcmp(i8* nocapture, i8* nocapture, i32) nounwind readonly
declare arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this)
declare arm_aapcs_vfpcc i8* @_ZNKSs7_M_dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this)
declare arm_aapcs_vfpcc i8* @_ZNKSs4dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this)