Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / convergent.ll
blob6ba51e06460c271522f7f925e8d4d8e4ccfda776
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck -check-prefixes=CHECK,NOSINK %s
3 ; RUN: opt -S -passes=simplifycfg < %s | FileCheck -check-prefixes=CHECK,NOSINK %s
4 ; RUN: opt -S -passes='simplifycfg<hoist-common-insts;sink-common-insts>' < %s | FileCheck -check-prefixes=CHECK,SINK %s
6 declare void @foo() convergent
7 declare i32 @tid()
8 declare i32 @mbcnt(i32 %a, i32 %b) convergent
9 declare i32 @bpermute(i32 %a, i32 %b) convergent
11 define i32 @test_01(i32 %a) {
12 ; CHECK-LABEL: @test_01(
13 ; CHECK-NEXT:  entry:
14 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[A:%.*]], 0
15 ; CHECK-NEXT:    br i1 [[COND]], label [[MERGE:%.*]], label [[IF_FALSE:%.*]]
16 ; CHECK:       if.false:
17 ; CHECK-NEXT:    call void @foo()
18 ; CHECK-NEXT:    br label [[MERGE]]
19 ; CHECK:       merge:
20 ; CHECK-NEXT:    call void @foo()
21 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[IF_FALSE_2:%.*]]
22 ; CHECK:       if.false.2:
23 ; CHECK-NEXT:    call void @foo()
24 ; CHECK-NEXT:    br label [[EXIT]]
25 ; CHECK:       exit:
26 ; CHECK-NEXT:    ret i32 [[A]]
28 entry:
29   %cond = icmp eq i32 %a, 0
30   br i1 %cond, label %merge, label %if.false
32 if.false:
33   call void @foo()
34   br label %merge
36 merge:
37   call void @foo()
38   br i1 %cond, label %exit, label %if.false.2
40 if.false.2:
41   call void @foo()
42   br label %exit
44 exit:
45   ret i32 %a
48 define void @test_02(ptr %y.coerce) convergent {
49 ; NOSINK-LABEL: @test_02(
50 ; NOSINK-NEXT:  entry:
51 ; NOSINK-NEXT:    [[TMP0:%.*]] = tail call i32 @tid()
52 ; NOSINK-NEXT:    [[REM:%.*]] = and i32 [[TMP0]], 1
53 ; NOSINK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[REM]], 0
54 ; NOSINK-NEXT:    br i1 [[CMP_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
55 ; NOSINK:       if.then:
56 ; NOSINK-NEXT:    [[TMP1:%.*]] = tail call i32 @mbcnt(i32 -1, i32 0)
57 ; NOSINK-NEXT:    [[TMP2:%.*]] = tail call i32 @mbcnt(i32 -1, i32 [[TMP1]])
58 ; NOSINK-NEXT:    [[AND_I:%.*]] = shl i32 [[TMP2]], 2
59 ; NOSINK-NEXT:    [[ADD_I:%.*]] = and i32 [[AND_I]], -256
60 ; NOSINK-NEXT:    [[SHL_I:%.*]] = or i32 [[ADD_I]], 16
61 ; NOSINK-NEXT:    [[TMP3:%.*]] = tail call i32 @bpermute(i32 [[SHL_I]], i32 [[TMP0]])
62 ; NOSINK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[TMP0]] to i64
63 ; NOSINK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[Y_COERCE:%.*]], i64 [[IDXPROM]]
64 ; NOSINK-NEXT:    store i32 [[TMP3]], ptr [[ARRAYIDX]], align 4
65 ; NOSINK-NEXT:    br label [[IF_END:%.*]]
66 ; NOSINK:       if.else:
67 ; NOSINK-NEXT:    [[TMP4:%.*]] = tail call i32 @mbcnt(i32 -1, i32 0)
68 ; NOSINK-NEXT:    [[TMP5:%.*]] = tail call i32 @mbcnt(i32 -1, i32 [[TMP4]])
69 ; NOSINK-NEXT:    [[AND_I11:%.*]] = shl i32 [[TMP5]], 2
70 ; NOSINK-NEXT:    [[ADD_I12:%.*]] = and i32 [[AND_I11]], -256
71 ; NOSINK-NEXT:    [[SHL_I13:%.*]] = or i32 [[ADD_I12]], 8
72 ; NOSINK-NEXT:    [[TMP6:%.*]] = tail call i32 @bpermute(i32 [[SHL_I13]], i32 [[TMP0]])
73 ; NOSINK-NEXT:    [[IDXPROM4:%.*]] = zext i32 [[TMP0]] to i64
74 ; NOSINK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[Y_COERCE]], i64 [[IDXPROM4]]
75 ; NOSINK-NEXT:    store i32 [[TMP6]], ptr [[ARRAYIDX5]], align 4
76 ; NOSINK-NEXT:    br label [[IF_END]]
77 ; NOSINK:       if.end:
78 ; NOSINK-NEXT:    ret void
80 ; SINK-LABEL: @test_02(
81 ; SINK-NEXT:  entry:
82 ; SINK-NEXT:    [[TMP0:%.*]] = tail call i32 @tid()
83 ; SINK-NEXT:    [[REM:%.*]] = and i32 [[TMP0]], 1
84 ; SINK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[REM]], 0
85 ; SINK-NEXT:    [[IDXPROM4:%.*]] = zext i32 [[TMP0]] to i64
86 ; SINK-NEXT:    [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, ptr [[Y_COERCE:%.*]], i64 [[IDXPROM4]]
87 ; SINK-NEXT:    br i1 [[CMP_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
88 ; SINK:       if.then:
89 ; SINK-NEXT:    [[TMP1:%.*]] = tail call i32 @mbcnt(i32 -1, i32 0)
90 ; SINK-NEXT:    [[TMP2:%.*]] = tail call i32 @mbcnt(i32 -1, i32 [[TMP1]])
91 ; SINK-NEXT:    [[AND_I:%.*]] = shl i32 [[TMP2]], 2
92 ; SINK-NEXT:    [[ADD_I:%.*]] = and i32 [[AND_I]], -256
93 ; SINK-NEXT:    [[SHL_I:%.*]] = or i32 [[ADD_I]], 16
94 ; SINK-NEXT:    [[TMP3:%.*]] = tail call i32 @bpermute(i32 [[SHL_I]], i32 [[TMP0]])
95 ; SINK-NEXT:    br label [[IF_END:%.*]]
96 ; SINK:       if.else:
97 ; SINK-NEXT:    [[TMP4:%.*]] = tail call i32 @mbcnt(i32 -1, i32 0)
98 ; SINK-NEXT:    [[TMP5:%.*]] = tail call i32 @mbcnt(i32 -1, i32 [[TMP4]])
99 ; SINK-NEXT:    [[AND_I11:%.*]] = shl i32 [[TMP5]], 2
100 ; SINK-NEXT:    [[ADD_I12:%.*]] = and i32 [[AND_I11]], -256
101 ; SINK-NEXT:    [[SHL_I13:%.*]] = or i32 [[ADD_I12]], 8
102 ; SINK-NEXT:    [[TMP6:%.*]] = tail call i32 @bpermute(i32 [[SHL_I13]], i32 [[TMP0]])
103 ; SINK-NEXT:    br label [[IF_END]]
104 ; SINK:       if.end:
105 ; SINK-NEXT:    [[DOTSINK:%.*]] = phi i32 [ [[TMP6]], [[IF_ELSE]] ], [ [[TMP3]], [[IF_THEN]] ]
106 ; SINK-NEXT:    store i32 [[DOTSINK]], ptr [[ARRAYIDX5]], align 4
107 ; SINK-NEXT:    ret void
109 entry:
110   %0 = tail call i32 @tid()
111   %rem = and i32 %0, 1
112   %cmp.not = icmp eq i32 %rem, 0
113   br i1 %cmp.not, label %if.else, label %if.then
115 if.then:
116   %1 = tail call i32 @mbcnt(i32 -1, i32 0)
117   %2 = tail call i32 @mbcnt(i32 -1, i32 %1)
118   %and.i = shl i32 %2, 2
119   %add.i = and i32 %and.i, -256
120   %shl.i = or i32 %add.i, 16
121   %3 = tail call i32 @bpermute(i32 %shl.i, i32 %0)
122   %idxprom = zext i32 %0 to i64
123   %arrayidx = getelementptr inbounds i32, ptr %y.coerce, i64 %idxprom
124   store i32 %3, ptr %arrayidx
125   br label %if.end
127 if.else:
128   %4 = tail call i32 @mbcnt(i32 -1, i32 0)
129   %5 = tail call i32 @mbcnt(i32 -1, i32 %4)
130   %and.i11 = shl i32 %5, 2
131   %add.i12 = and i32 %and.i11, -256
132   %shl.i13 = or i32 %add.i12, 8
133   %6 = tail call i32 @bpermute(i32 %shl.i13, i32 %0)
134   %idxprom4 = zext i32 %0 to i64
135   %arrayidx5 = getelementptr inbounds i32, ptr %y.coerce, i64 %idxprom4
136   store i32 %6, ptr %arrayidx5
137   br label %if.end
139 if.end:
140   ret void