1 ; RUN: opt -S -licm < %s | FileCheck %s 2 ; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' -S %s | FileCheck %s 3 4 declare void @use_nothrow(i64 %a) nounwind 5 declare void @use(i64 %a) 6 7 define void @nothrow(i64 %x, i64 %y, i1* %cond) { 8 ; CHECK-LABEL: nothrow 9 ; CHECK-LABEL: entry 10 ; CHECK: %div = udiv i64 %x, %y 11 ; CHECK-LABEL: loop 12 ; CHECK: call void @use_nothrow(i64 %div) 13 entry: 14 br label %loop 15 16 loop: ; preds = %entry, %for.inc 17 %div = udiv i64 %x, %y 18 br label %loop2 19 20 loop2: 21 call void @use_nothrow(i64 %div) 22 br label %loop 23 } 24 ; Negative test 25 define void @throw_header(i64 %x, i64 %y, i1* %cond) { 26 ; CHECK-LABEL: throw_header 27 ; CHECK-LABEL: loop 28 ; CHECK: %div = udiv i64 %x, %y 29 ; CHECK: call void @use(i64 %div) 30 entry: 31 br label %loop 32 33 loop: ; preds = %entry, %for.inc 34 %div = udiv i64 %x, %y 35 call void @use(i64 %div) 36 br label %loop 37 } 38 39 ; The header is known no throw, but the loop is not. We can 40 ; still lift out of the header. 41 define void @nothrow_header(i64 %x, i64 %y, i1 %cond) { 42 ; CHECK-LABEL: nothrow_header 43 ; CHECK-LABEL: entry 44 ; CHECK: %div = udiv i64 %x, %y 45 ; CHECK-LABEL: loop 46 ; CHECK: call void @use(i64 %div) 47 entry: 48 br label %loop 49 loop: ; preds = %entry, %for.inc 50 %div = udiv i64 %x, %y 51 br i1 %cond, label %loop-if, label %exit 52 loop-if: 53 call void @use(i64 %div) 54 br label %loop 55 exit: 56 ret void 57 } 58 ; Negative test - can't move out of throwing block 59 define void @nothrow_header_neg(i64 %x, i64 %y, i1 %cond) { 60 ; CHECK-LABEL: nothrow_header_neg 61 ; CHECK-LABEL: entry 62 ; CHECK-LABEL: loop 63 ; CHECK: %div = udiv i64 %x, %y 64 ; CHECK: call void @use(i64 %div) 65 entry: 66 br label %loop 67 loop: ; preds = %entry, %for.inc 68 br label %loop-if 69 loop-if: 70 %div = udiv i64 %x, %y 71 call void @use(i64 %div) 72 br label %loop 73 } 74