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