1 ; RUN: opt -S -loop-versioning-licm -licm-versioning-invariant-threshold=0 %s | FileCheck %s
3 ; Make sure the convergent attribute is respected, and no condition is
6 ; CHECK-LABEL: @test_convergent(
7 ; CHECK: call void @llvm.convergent()
8 ; CHECK-NOT: call void @llvm.convergent()
9 define i32 @test_convergent(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #1 {
11 %cmp14 = icmp eq i32 %itr, 0
12 br i1 %cmp14, label %for.end13, label %for.cond1.preheader
14 for.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
20 for.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, i32* %var3, i64 %idxprom6
26 for.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, i32* %var1, i64 %idxprom
30 store i32 %add, i32* %arrayidx, align 4
31 %load.arrayidx7 = load i32, i32* %arrayidx7, align 4
32 call void @llvm.convergent()
33 %add8 = add nsw i32 %load.arrayidx7, %add
34 store i32 %add8, i32* %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
39 for.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
45 for.end13: ; preds = %for.inc11, %entry
49 ; CHECK-LABEL: @test_noduplicate(
50 ; CHECK: call void @llvm.noduplicate()
51 ; CHECK-NOT: call void @llvm.noduplicate()
52 define i32 @test_noduplicate(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #2 {
54 %cmp14 = icmp eq i32 %itr, 0
55 br i1 %cmp14, label %for.end13, label %for.cond1.preheader
57 for.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
63 for.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, i32* %var3, i64 %idxprom6
69 for.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, i32* %var1, i64 %idxprom
73 store i32 %add, i32* %arrayidx, align 4
74 %load.arrayidx7 = load i32, i32* %arrayidx7, align 4
75 call void @llvm.noduplicate()
76 %add8 = add nsw i32 %load.arrayidx7, %add
77 store i32 %add8, i32* %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
82 for.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
88 for.end13: ; preds = %for.inc11, %entry
92 declare void @llvm.convergent() #1
93 declare void @llvm.noduplicate() #2
95 attributes #0 = { norecurse nounwind }
96 attributes #1 = { norecurse nounwind readnone convergent }
97 attributes #2 = { norecurse nounwind readnone noduplicate }