1; RUN: opt -mtriple=amdgcn-- -O3 -S -enable-new-pm=0 %s | FileCheck %s 2 3; This fails with the new pass manager: 4; https://bugs.llvm.org/show_bug.cgi?id=48819 5 6; Check that loop unswitch happened and condition hoisted out of the loop. 7; Condition is uniform so all targets should perform unswitching. 8 9; CHECK-LABEL: {{^}}define amdgpu_kernel void @uniform_unswitch 10; CHECK: entry: 11; CHECK-NEXT: [[LOOP_COND:%[a-z0-9]+]] = icmp 12; CHECK-NEXT: [[IF_COND:%[a-z0-9]+]] = icmp eq i32 %x, 123456 13; CHECK-NEXT: and i1 [[LOOP_COND]], [[IF_COND]] 14; CHECK-NEXT: br i1 15 16define amdgpu_kernel void @uniform_unswitch(i32 * nocapture %out, i32 %n, i32 %x) { 17entry: 18 %cmp6 = icmp sgt i32 %n, 0 19 br i1 %cmp6, label %for.body.lr.ph, label %for.cond.cleanup 20 21for.body.lr.ph: ; preds = %entry 22 %cmp1 = icmp eq i32 %x, 123456 23 br label %for.body 24 25for.cond.cleanup.loopexit: ; preds = %for.inc 26 br label %for.cond.cleanup 27 28for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 29 ret void 30 31for.body: ; preds = %for.inc, %for.body.lr.ph 32 %i.07 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 33 br i1 %cmp1, label %if.then, label %for.inc 34 35if.then: ; preds = %for.body 36 %arrayidx = getelementptr inbounds i32, i32 * %out, i32 %i.07 37 store i32 %i.07, i32 * %arrayidx, align 4 38 br label %for.inc 39 40for.inc: ; preds = %for.body, %if.then 41 %inc = add nuw nsw i32 %i.07, 1 42 %exitcond = icmp eq i32 %inc, %n 43 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body 44} 45 46; Check that loop unswitch does not happen if condition is divergent. 47 48; CHECK-LABEL: {{^}}define amdgpu_kernel void @divergent_unswitch 49; CHECK: entry: 50; CHECK: icmp 51; CHECK: [[IF_COND:%[a-z0-9]+]] = icmp {{.*}} 567890 52; CHECK: br label 53; CHECK: br i1 [[IF_COND]] 54 55define amdgpu_kernel void @divergent_unswitch(i32 * nocapture %out, i32 %n) { 56entry: 57 %cmp9 = icmp sgt i32 %n, 0 58 br i1 %cmp9, label %for.body.lr.ph, label %for.cond.cleanup 59 60for.body.lr.ph: ; preds = %entry 61 %call = tail call i32 @llvm.amdgcn.workitem.id.x() #0 62 %cmp2 = icmp eq i32 %call, 567890 63 br label %for.body 64 65for.cond.cleanup.loopexit: ; preds = %for.inc 66 br label %for.cond.cleanup 67 68for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry 69 ret void 70 71for.body: ; preds = %for.inc, %for.body.lr.ph 72 %i.010 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ] 73 br i1 %cmp2, label %if.then, label %for.inc 74 75if.then: ; preds = %for.body 76 %arrayidx = getelementptr inbounds i32, i32 * %out, i32 %i.010 77 store i32 %i.010, i32 * %arrayidx, align 4 78 br label %for.inc 79 80for.inc: ; preds = %for.body, %if.then 81 %inc = add nuw nsw i32 %i.010, 1 82 %exitcond = icmp eq i32 %inc, %n 83 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body 84} 85 86declare i32 @llvm.amdgcn.workitem.id.x() #0 87 88attributes #0 = { nounwind readnone } 89