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