PR8921: LDM/POP do not support interworking prior to v5t.
authorBob Wilson <bob.wilson@apple.com>
Thu, 6 Jan 2011 19:24:41 +0000 (19:24 +0000)
committerBob Wilson <bob.wilson@apple.com>
Thu, 6 Jan 2011 19:24:41 +0000 (19:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122970 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMFrameInfo.cpp
lib/Target/ARM/ARMLoadStoreOptimizer.cpp
test/CodeGen/ARM/2010-03-18-ldm-rtrn.ll
test/CodeGen/ARM/bx_fold.ll
test/CodeGen/ARM/ifcvt6.ll
test/CodeGen/ARM/ifcvt7.ll
test/CodeGen/ARM/ifcvt8.ll
test/CodeGen/ARM/ldm.ll
test/CodeGen/ARM/lsr-code-insertion.ll

index bddc7987b17104812afd8cbd693366166ad01543..cbc06160d3d25bb5b6cb18a32ae5bab14991f538 100644 (file)
@@ -592,7 +592,7 @@ void ARMFrameInfo::emitPopInst(MachineBasicBlock &MBB,
       unsigned Reg = CSI[i-1].getReg();
       if (!(Func)(Reg, STI.isTargetDarwin())) continue;
 
-      if (Reg == ARM::LR && !isVarArg) {
+      if (Reg == ARM::LR && !isVarArg && STI.hasV5TOps()) {
         Reg = ARM::PC;
         LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
         // Fold the return instruction into the LDM.
index a544029e5abd382fda7829ea004d88ae0f205b36..f2d705f0ec5ab994ce2797efc7c92db487a2dd60 100644 (file)
@@ -1390,7 +1390,8 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
        ++MFI) {
     MachineBasicBlock &MBB = *MFI;
     Modified |= LoadStoreMultipleOpti(MBB);
-    Modified |= MergeReturnIntoLDM(MBB);
+    if (TM.getSubtarget<ARMSubtarget>().hasV5TOps())
+      Modified |= MergeReturnIntoLDM(MBB);
   }
 
   delete RS;
index 31525eff446126c171738737347dc059ef74124d..d9e1a1486a3cd95e0807f3638d38667d268f5c8d 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s
+; RUN: llc < %s -mtriple=armv4-unknown-eabi | FileCheck %s -check-prefix=V4
 ; RUN: llc < %s -mtriple=armv5-unknown-eabi | FileCheck %s
 ; RUN: llc < %s -mtriple=armv6-unknown-eabi | FileCheck %s
 
@@ -7,6 +7,8 @@ entry:
   %0 = tail call i32 @foo(i32 %a) nounwind ; <i32> [#uses=1]
   %1 = add nsw i32 %0, 3                          ; <i32> [#uses=1]
 ; CHECK: ldmia sp!, {r11, pc}
+; V4: pop
+; V4-NEXT: mov pc, lr
   ret i32 %1
 }
 
index 0e3e070a818fa1cf715025294fe9b7a79b0f6d4f..09f1aae0a9f0dbea39a1121f8d34ce048cc2ef96 100644 (file)
@@ -1,5 +1,4 @@
-; RUN: llc < %s -march=arm
-; RUN: llc < %s -march=arm | not grep bx
+; RUN: llc < %s -mtriple=armv5t-apple-darwin | FileCheck %s
 
 define void @test(i32 %Ptr, i8* %L) {
 entry:
@@ -24,6 +23,8 @@ bb1:          ; preds = %bb, %entry
        br i1 %bothcond, label %bb, label %bb18
 
 bb18:          ; preds = %bb1
+; CHECK-NOT: bx
+; CHECK: ldmia sp!
        ret void
 }
 
index e2c0ba398c68dc87c9d85ff0ac29496808b7e8b0..5edf32fd1af677601dab255631114b480f0f428c 100644 (file)
@@ -1,10 +1,9 @@
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep cmpne | count 1
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep ldmiahi | count 1
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
 
 define void @foo(i32 %X, i32 %Y) {
 entry:
+; CHECK: cmpne
+; CHECK: ldmiahi sp!
        %tmp1 = icmp ult i32 %X, 4              ; <i1> [#uses=1]
        %tmp4 = icmp eq i32 %Y, 0               ; <i1> [#uses=1]
        %tmp7 = or i1 %tmp4, %tmp1              ; <i1> [#uses=1]
index eb97085ac00407327dbc44b69768eb395d7de898..62e13557cfdc09670a9b98b1227568e1e67cc24b 100644 (file)
@@ -1,14 +1,12 @@
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep cmpeq | count 1
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep moveq | count 1
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep ldmiaeq | count 1
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
 ; FIXME: Need post-ifcvt branch folding to get rid of the extra br at end of BB1.
 
        %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
 
 define fastcc i32 @CountTree(%struct.quad_struct* %tree) {
+; CHECK: cmpeq
+; CHECK: moveq
+; CHECK: ldmiaeq sp!
 entry:
        br label %tailrecurse
 
index 1e39060e69f2e3d6220a820f67989ded6f502c40..5fdfc4ea6805912ef701e2d6b42e0aa700b870fa 100644 (file)
@@ -1,11 +1,11 @@
-; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
-; RUN:   grep ldmiane | count 1
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
 
        %struct.SString = type { i8*, i32, i32 }
 
 declare void @abort()
 
 define fastcc void @t(%struct.SString* %word, i8 signext  %c) {
+; CHECK: ldmiane sp!
 entry:
        %tmp1 = icmp eq %struct.SString* %word, null            ; <i1> [#uses=1]
        br i1 %tmp1, label %cond_true, label %cond_false
index 78201a6b341ac8ad24a7519be3333a148f1b84b2..2f1b85ebbb043f64e57996b2fce89b983d79dcba 100644 (file)
@@ -1,10 +1,13 @@
-; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
+; RUN: llc < %s -mtriple=armv4t-apple-darwin | FileCheck %s -check-prefix=V4T
 
 @X = external global [0 x i32]          ; <[0 x i32]*> [#uses=5]
 
 define i32 @t1() {
 ; CHECK: t1:
 ; CHECK: ldmia
+; V4T: t1:
+; V4T: ldmia
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 0)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1)           ; <i32> [#uses=1]
         %tmp4 = tail call i32 @f1( i32 %tmp, i32 %tmp3 )                ; <i32> [#uses=1]
@@ -14,6 +17,8 @@ define i32 @t1() {
 define i32 @t2() {
 ; CHECK: t2:
 ; CHECK: ldmia
+; V4T: t2:
+; V4T: ldmia
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3)           ; <i32> [#uses=1]
         %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 4)           ; <i32> [#uses=1]
@@ -25,6 +30,10 @@ define i32 @t3() {
 ; CHECK: t3:
 ; CHECK: ldmib
 ; CHECK: ldmia sp!
+; V4T: t3:
+; V4T: ldmib
+; V4T: pop
+; V4T-NEXT: bx lr
         %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1)            ; <i32> [#uses=1]
         %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2)           ; <i32> [#uses=1]
         %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3)           ; <i32> [#uses=1]
index b8c543b1bd189da31df028e352d8d9598147d1a4..1bbb96deeefefcc453d54675924b97113dd220e5 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: llc < %s -stats |& grep {38.*Number of machine instrs printed}
+; RUN: llc < %s -stats |& grep {39.*Number of machine instrs printed}
 ; RUN: llc < %s -stats |& not grep {.*Number of re-materialization}
 ; This test really wants to check that the resultant "cond_true" block only 
 ; has a single store in it, and that cond_true55 only has code to materialize