1; REQUIRES: asserts 2; RUN: opt -loop-unswitch -enable-new-pm=0 -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s 3; RUN: opt -loop-unswitch -enable-new-pm=0 -enable-mssa-loop-dependency=true -verify-memoryssa -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s 4; RUN: opt -loop-unswitch -enable-new-pm=0 -simplifycfg -S < %s | FileCheck %s 5; PR5373 6 7; Loop unswitching shouldn't trivially unswitch the true case of condition %a 8; in the code here because it leads to an infinite loop. While this doesn't 9; contain any instructions with side effects, it's still a kind of side effect. 10; It can trivially unswitch on the false case of condition %a though. 11 12; STATS: 2 loop-unswitch - Number of branches unswitched 13; STATS: 2 loop-unswitch - Number of unswitches that are trivial 14 15; CHECK-LABEL: @func_16( 16; CHECK-NEXT: entry: 17; CHECK-NEXT: br i1 %a, label %entry.split, label %abort0.split 18 19; CHECK: entry.split: 20; CHECK-NEXT: br i1 %b, label %for.body, label %abort1.split 21 22; CHECK: for.body: 23; CHECK-NEXT: br label %for.body 24 25; CHECK: abort0.split: 26; CHECK-NEXT: call void @end0() [[NOR_NUW:#[0-9]+]] 27; CHECK-NEXT: unreachable 28 29; CHECK: abort1.split: 30; CHECK-NEXT: call void @end1() [[NOR_NUW]] 31; CHECK-NEXT: unreachable 32 33; CHECK: } 34 35define void @func_16(i1 %a, i1 %b) nounwind { 36entry: 37 br label %for.body 38 39for.body: 40 br i1 %a, label %cond.end, label %abort0 41 42cond.end: 43 br i1 %b, label %for.body, label %abort1 44 45abort0: 46 call void @end0() noreturn nounwind 47 unreachable 48 49abort1: 50 call void @end1() noreturn nounwind 51 unreachable 52} 53 54declare void @end0() noreturn 55declare void @end1() noreturn 56 57; CHECK: attributes #0 = { nounwind } 58; CHECK: attributes #1 = { noreturn } 59; CHECK: attributes [[NOR_NUW]] = { noreturn nounwind } 60