1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -simplifycfg -S < %s | FileCheck %s --check-prefixes=HOIST,DEFAULT 3 4; This example is produced from a very basic C code: 5; 6; void f0(); 7; void f1(); 8; void f2(); 9; 10; void loop(int width) { 11; if(width < 1) 12; return; 13; for(int i = 0; i < width - 1; ++i) { 14; f0(); 15; f1(); 16; } 17; f0(); 18; f2(); 19; } 20 21; We have a choice here. We can either 22; * hoist the f0() call into loop header, 23; * which potentially makes loop rotation unprofitable since loop header might 24; have grown above certain threshold, and such unrotated loops will be 25; ignored by LoopVectorizer, preventing vectorization 26; * or loop rotation will succeed, resulting in some weird PHIs that will also 27; harm vectorization 28; * or not hoist f0() call before performing loop rotation, 29; at the cost of potential code bloat and/or potentially successfully rotating 30; the loops, vectorizing them at the cost of compile time. 31 32target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 33 34declare i1 @gen1() 35 36declare void @f0() 37declare void @f1() 38declare void @f2() 39 40declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) 41declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) 42 43define void @_Z4loopi(i1 %cmp) { 44; HOIST-LABEL: @_Z4loopi( 45; HOIST-NEXT: entry: 46; HOIST-NEXT: br i1 [[CMP:%.*]], label [[RETURN:%.*]], label [[FOR_COND:%.*]] 47; HOIST: for.cond: 48; HOIST-NEXT: [[CMP1:%.*]] = call i1 @gen1() 49; HOIST-NEXT: call void @f0() 50; HOIST-NEXT: br i1 [[CMP1]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 51; HOIST: for.body: 52; HOIST-NEXT: call void @f1() 53; HOIST-NEXT: br label [[FOR_COND]] 54; HOIST: for.end: 55; HOIST-NEXT: call void @f2() 56; HOIST-NEXT: br label [[RETURN]] 57; HOIST: return: 58; HOIST-NEXT: ret void 59; 60entry: 61 br i1 %cmp, label %if.then, label %if.end 62 63if.then: 64 br label %return 65 66if.end: 67 br label %for.cond 68 69for.cond: 70 %cmp1 = call i1 @gen1() 71 br i1 %cmp1, label %for.body, label %for.cond.cleanup 72 73for.cond.cleanup: 74 br label %for.end 75 76for.body: 77 call void @f0() 78 call void @f1() 79 br label %for.inc 80 81for.inc: 82 br label %for.cond 83 84for.end: 85 call void @f0() 86 call void @f2() 87 br label %return 88 89return: 90 ret void 91} 92