1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt < %s -passes=indvars -S | FileCheck %s
;
; PR1301
; Do a bunch of analysis and prove that the loops can use an i32 trip
; count without casting.
;
; Note that all four functions should actually be converted to
; memset. However, this test case validates indvars behavior. We
; don't check that phis are "folded together" because that is a job
; for loop strength reduction. But indvars must remove sext, zext, and add i8.
;
; ModuleID = 'ada.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32"
target triple = "i686-pc-linux-gnu"
define void @kinds__sbytezero(ptr nocapture %a) nounwind {
; CHECK-LABEL: define void @kinds__sbytezero(
; CHECK-SAME: ptr captures(none) [[A:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: bb.thread:
; CHECK-NEXT: [[TMP46:%.*]] = getelementptr [256 x i32], ptr [[A]], i32 0, i32 0
; CHECK-NEXT: store i32 0, ptr [[TMP46]], align 4
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ -128, [[BB_THREAD:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], 1
; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[INDVARS_IV_NEXT]], 128
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [256 x i32], ptr [[A]], i32 0, i32 [[TMP3]]
; CHECK-NEXT: store i32 0, ptr [[TMP4]], align 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 127
; CHECK-NEXT: br i1 [[TMP0]], label [[RETURN:%.*]], label [[BB]]
; CHECK: return:
; CHECK-NEXT: ret void
;
bb.thread:
%tmp46 = getelementptr [256 x i32], ptr %a, i32 0, i32 0 ; <ptr> [#uses=1]
store i32 0, ptr %tmp46
br label %bb
bb: ; preds = %bb, %bb.thread
%i.0.reg2mem.0 = phi i8 [ -128, %bb.thread ], [ %tmp8, %bb ] ; <i8> [#uses=1]
%tmp8 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=3]
%tmp1 = sext i8 %tmp8 to i32 ; <i32> [#uses=1]
%tmp3 = add i32 %tmp1, 128 ; <i32> [#uses=1]
%tmp4 = getelementptr [256 x i32], ptr %a, i32 0, i32 %tmp3 ; <ptr> [#uses=1]
store i32 0, ptr %tmp4
%0 = icmp eq i8 %tmp8, 127 ; <i1> [#uses=1]
br i1 %0, label %return, label %bb
return: ; preds = %bb
ret void
}
define void @kinds__ubytezero(ptr nocapture %a) nounwind {
; CHECK-LABEL: define void @kinds__ubytezero(
; CHECK-SAME: ptr captures(none) [[A:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: bb.thread:
; CHECK-NEXT: [[TMP35:%.*]] = getelementptr [256 x i32], ptr [[A]], i32 0, i32 0
; CHECK-NEXT: store i32 0, ptr [[TMP35]], align 4
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ 0, [[BB_THREAD:%.*]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr [256 x i32], ptr [[A]], i32 0, i32 [[INDVARS_IV_NEXT]]
; CHECK-NEXT: store i32 0, ptr [[TMP3]], align 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 255
; CHECK-NEXT: br i1 [[TMP0]], label [[RETURN:%.*]], label [[BB]]
; CHECK: return:
; CHECK-NEXT: ret void
;
bb.thread:
%tmp35 = getelementptr [256 x i32], ptr %a, i32 0, i32 0 ; <ptr> [#uses=1]
store i32 0, ptr %tmp35
br label %bb
bb: ; preds = %bb, %bb.thread
%i.0.reg2mem.0 = phi i8 [ 0, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=1]
%tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=3]
%tmp1 = zext i8 %tmp7 to i32 ; <i32> [#uses=1]
%tmp3 = getelementptr [256 x i32], ptr %a, i32 0, i32 %tmp1 ; <ptr> [#uses=1]
store i32 0, ptr %tmp3
%0 = icmp eq i8 %tmp7, -1 ; <i1> [#uses=1]
br i1 %0, label %return, label %bb
return: ; preds = %bb
ret void
}
define void @kinds__srangezero(ptr nocapture %a) nounwind {
; CHECK-LABEL: define void @kinds__srangezero(
; CHECK-SAME: ptr captures(none) [[A:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: bb.thread:
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ -10, [[BB_THREAD:%.*]] ]
; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[INDVARS_IV]], 10
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [21 x i32], ptr [[A]], i32 0, i32 [[TMP4]]
; CHECK-NEXT: store i32 0, ptr [[TMP5]], align 4
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 11
; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[BB]]
; CHECK: return:
; CHECK-NEXT: ret void
;
bb.thread:
br label %bb
bb: ; preds = %bb, %bb.thread
%i.0.reg2mem.0 = phi i8 [ -10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2]
%tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1]
%tmp4 = add i32 %tmp12, 10 ; <i32> [#uses=1]
%tmp5 = getelementptr [21 x i32], ptr %a, i32 0, i32 %tmp4 ; <ptr> [#uses=1]
store i32 0, ptr %tmp5
%tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2]
%0 = icmp sgt i8 %tmp7, 10 ; <i1> [#uses=1]
br i1 %0, label %return, label %bb
return: ; preds = %bb
ret void
}
define void @kinds__urangezero(ptr nocapture %a) nounwind {
; CHECK-LABEL: define void @kinds__urangezero(
; CHECK-SAME: ptr captures(none) [[A:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: bb.thread:
; CHECK-NEXT: br label [[BB:%.*]]
; CHECK: bb:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i32 [ [[INDVARS_IV_NEXT:%.*]], [[BB]] ], [ 10, [[BB_THREAD:%.*]] ]
; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[INDVARS_IV]], -10
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr [21 x i32], ptr [[A]], i32 0, i32 [[TMP4]]
; CHECK-NEXT: store i32 0, ptr [[TMP5]], align 4
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i32 [[INDVARS_IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[INDVARS_IV_NEXT]], 31
; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN:%.*]], label [[BB]]
; CHECK: return:
; CHECK-NEXT: ret void
;
bb.thread:
br label %bb
bb: ; preds = %bb, %bb.thread
%i.0.reg2mem.0 = phi i8 [ 10, %bb.thread ], [ %tmp7, %bb ] ; <i8> [#uses=2]
%tmp12 = sext i8 %i.0.reg2mem.0 to i32 ; <i32> [#uses=1]
%tmp4 = add i32 %tmp12, -10 ; <i32> [#uses=1]
%tmp5 = getelementptr [21 x i32], ptr %a, i32 0, i32 %tmp4 ; <ptr> [#uses=1]
store i32 0, ptr %tmp5
%tmp7 = add i8 %i.0.reg2mem.0, 1 ; <i8> [#uses=2]
%0 = icmp sgt i8 %tmp7, 30 ; <i1> [#uses=1]
br i1 %0, label %return, label %bb
return: ; preds = %bb
ret void
}
|