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