1; RUN: opt -S -passes='loop-versioning-licm' -licm-versioning-invariant-threshold=0 %s | FileCheck %s 2 3; Make sure the convergent attribute is respected, and no condition is 4; introduced 5 6; CHECK-LABEL: @test_convergent( 7; CHECK: call void @llvm.convergent() 8; CHECK-NOT: call void @llvm.convergent() 9define i32 @test_convergent(ptr nocapture %var1, ptr nocapture readnone %var2, ptr nocapture %var3, i32 %itr) #1 { 10entry: 11 %cmp14 = icmp eq i32 %itr, 0 12 br i1 %cmp14, label %for.end13, label %for.cond1.preheader 13 14for.cond1.preheader: ; preds = %entry, %for.inc11 15 %j.016 = phi i32 [ %j.1.lcssa, %for.inc11 ], [ 0, %entry ] 16 %i.015 = phi i32 [ %inc12, %for.inc11 ], [ 0, %entry ] 17 %cmp212 = icmp ult i32 %j.016, %itr 18 br i1 %cmp212, label %for.body3.lr.ph, label %for.inc11 19 20for.body3.lr.ph: ; preds = %for.cond1.preheader 21 %add = add i32 %i.015, %itr 22 %idxprom6 = zext i32 %i.015 to i64 23 %arrayidx7 = getelementptr inbounds i32, ptr %var3, i64 %idxprom6 24 br label %for.body3 25 26for.body3: ; preds = %for.body3, %for.body3.lr.ph 27 %j.113 = phi i32 [ %j.016, %for.body3.lr.ph ], [ %inc, %for.body3 ] 28 %idxprom = zext i32 %j.113 to i64 29 %arrayidx = getelementptr inbounds i32, ptr %var1, i64 %idxprom 30 store i32 %add, ptr %arrayidx, align 4 31 %load.arrayidx7 = load i32, ptr %arrayidx7, align 4 32 call void @llvm.convergent() 33 %add8 = add nsw i32 %load.arrayidx7, %add 34 store i32 %add8, ptr %arrayidx7, align 4 35 %inc = add nuw i32 %j.113, 1 36 %cmp2 = icmp ult i32 %inc, %itr 37 br i1 %cmp2, label %for.body3, label %for.inc11 38 39for.inc11: ; preds = %for.body3, %for.cond1.preheader 40 %j.1.lcssa = phi i32 [ %j.016, %for.cond1.preheader ], [ %itr, %for.body3 ] 41 %inc12 = add nuw i32 %i.015, 1 42 %cmp = icmp ult i32 %inc12, %itr 43 br i1 %cmp, label %for.cond1.preheader, label %for.end13 44 45for.end13: ; preds = %for.inc11, %entry 46 ret i32 0 47} 48 49; CHECK-LABEL: @test_noduplicate( 50; CHECK: call void @llvm.noduplicate() 51; CHECK-NOT: call void @llvm.noduplicate() 52define i32 @test_noduplicate(ptr nocapture %var1, ptr nocapture readnone %var2, ptr nocapture %var3, i32 %itr) #2 { 53entry: 54 %cmp14 = icmp eq i32 %itr, 0 55 br i1 %cmp14, label %for.end13, label %for.cond1.preheader 56 57for.cond1.preheader: ; preds = %entry, %for.inc11 58 %j.016 = phi i32 [ %j.1.lcssa, %for.inc11 ], [ 0, %entry ] 59 %i.015 = phi i32 [ %inc12, %for.inc11 ], [ 0, %entry ] 60 %cmp212 = icmp ult i32 %j.016, %itr 61 br i1 %cmp212, label %for.body3.lr.ph, label %for.inc11 62 63for.body3.lr.ph: ; preds = %for.cond1.preheader 64 %add = add i32 %i.015, %itr 65 %idxprom6 = zext i32 %i.015 to i64 66 %arrayidx7 = getelementptr inbounds i32, ptr %var3, i64 %idxprom6 67 br label %for.body3 68 69for.body3: ; preds = %for.body3, %for.body3.lr.ph 70 %j.113 = phi i32 [ %j.016, %for.body3.lr.ph ], [ %inc, %for.body3 ] 71 %idxprom = zext i32 %j.113 to i64 72 %arrayidx = getelementptr inbounds i32, ptr %var1, i64 %idxprom 73 store i32 %add, ptr %arrayidx, align 4 74 %load.arrayidx7 = load i32, ptr %arrayidx7, align 4 75 call void @llvm.noduplicate() 76 %add8 = add nsw i32 %load.arrayidx7, %add 77 store i32 %add8, ptr %arrayidx7, align 4 78 %inc = add nuw i32 %j.113, 1 79 %cmp2 = icmp ult i32 %inc, %itr 80 br i1 %cmp2, label %for.body3, label %for.inc11 81 82for.inc11: ; preds = %for.body3, %for.cond1.preheader 83 %j.1.lcssa = phi i32 [ %j.016, %for.cond1.preheader ], [ %itr, %for.body3 ] 84 %inc12 = add nuw i32 %i.015, 1 85 %cmp = icmp ult i32 %inc12, %itr 86 br i1 %cmp, label %for.cond1.preheader, label %for.end13 87 88for.end13: ; preds = %for.inc11, %entry 89 ret i32 0 90} 91 92declare void @llvm.convergent() #1 93declare void @llvm.noduplicate() #2 94 95attributes #0 = { norecurse nounwind } 96attributes #1 = { norecurse nounwind readnone convergent } 97attributes #2 = { norecurse nounwind readnone noduplicate } 98