Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a9 -jump-table-density=40 | FileCheck %s
      2 ; Test that ldmia_ret preserves implicit operands for return values.
      3 ;
      4 ; This CFG is reduced from a benchmark miscompile. With current
      5 ; if-conversion heuristics, one of the return paths is if-converted
      6 ; into sw.bb18 resulting in an ldmia_ret in the middle of the
      7 ; block. The postra scheduler needs to know that the return implicitly
      8 ; uses the return register, otherwise its antidep breaker scavenges
      9 ; the register in order to hoist the constant load required to test
     10 ; the switch.
     11 
     12 declare i32 @getint()
     13 declare i1 @getbool()
     14 declare void @foo(i32)
     15 declare i32 @bar(i32)
     16 
     17 define i32 @test(i32 %in1, i32 %in2) nounwind {
     18 entry:
     19   %call = tail call zeroext i1 @getbool() nounwind
     20   br i1 %call, label %sw.bb18, label %sw.bb2
     21 
     22 sw.bb2:                                           ; preds = %entry
     23   %cmp = tail call zeroext i1 @getbool() nounwind
     24   br i1 %cmp, label %sw.epilog58, label %land.lhs.true
     25 
     26 land.lhs.true:                                    ; preds = %sw.bb2
     27   %cmp13 = tail call zeroext i1 @getbool() nounwind
     28   br i1 %cmp13, label %if.then, label %sw.epilog58
     29 
     30 if.then:                                          ; preds = %land.lhs.true
     31   tail call void @foo(i32 %in1) nounwind
     32   br label %sw.epilog58
     33 
     34 ; load the return value
     35 ; CHECK: movs	[[RRET:r.]], #2
     36 ; hoist the switch constant without clobbering RRET
     37 ; CHECK: movw
     38 ; CHECK-NOT: [[RRET]]
     39 ; CHECK: , #63707
     40 ; CHECK-NOT: [[RRET]]
     41 ; CHECK: tst
     42 ; If-convert the return
     43 ; CHECK: it	ne
     44 ; Fold the CSR+return into a pop
     45 ; CHECK: pop {r4, r5, r7, pc}
     46 sw.bb18:
     47   %call20 = tail call i32 @bar(i32 %in2) nounwind
     48   switch i32 %call20, label %sw.default56 [
     49     i32 168, label %sw.bb21
     50     i32 165, label %sw.bb21
     51     i32 261, label %sw.epilog58
     52     i32 188, label %sw.epilog58
     53     i32 187, label %sw.epilog58
     54     i32 186, label %sw.epilog58
     55     i32 185, label %sw.epilog58
     56     i32 184, label %sw.epilog58
     57     i32 175, label %sw.epilog58
     58     i32 174, label %sw.epilog58
     59     i32 173, label %sw.epilog58
     60     i32 172, label %sw.epilog58
     61     i32 171, label %sw.epilog58
     62     i32 167, label %sw.epilog58
     63     i32 166, label %sw.epilog58
     64     i32 164, label %sw.epilog58
     65     i32 163, label %sw.epilog58
     66     i32 161, label %sw.epilog58
     67     i32 160, label %sw.epilog58
     68     i32 -1, label %sw.bb33
     69   ]
     70 
     71 sw.bb21:                                          ; preds = %sw.bb18, %sw.bb18
     72   tail call void @foo(i32 %in2) nounwind
     73   %call28 = tail call i32 @getint() nounwind
     74   %tobool = icmp eq i32 %call28, 0
     75   br i1 %tobool, label %if.then29, label %sw.epilog58
     76 
     77 if.then29:                                        ; preds = %sw.bb21
     78   tail call void @foo(i32 %in2) nounwind
     79   br label %sw.epilog58
     80 
     81 sw.bb33:                                          ; preds = %sw.bb18
     82   %cmp42 = tail call zeroext i1 @getbool() nounwind
     83   br i1 %cmp42, label %sw.default56, label %land.lhs.true44
     84 
     85 land.lhs.true44:                                  ; preds = %sw.bb33
     86   %call50 = tail call i32 @getint() nounwind
     87   %cmp51 = icmp slt i32 %call50, 0
     88   br i1 %cmp51, label %if.then53, label %sw.default56
     89 
     90 if.then53:                                        ; preds = %land.lhs.true44
     91   tail call void @foo(i32 %in2) nounwind
     92   br label %sw.default56
     93 
     94 sw.default56:                                     ; preds = %sw.bb33, %land.lhs.true44, %if.then53, %sw.bb18
     95   br label %sw.epilog58
     96 
     97 sw.epilog58:
     98   %retval.0 = phi i32 [ 4, %sw.default56 ], [ 2, %sw.bb21 ], [ 2, %if.then29 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb2 ], [ 2, %land.lhs.true ], [ 2, %if.then ]
     99   ret i32 %retval.0
    100 }
    101