1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define void @f(i64 %val, i32 %limit, i32 *%ptr) {
7 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32
8 ; CHECK-NEXT: br label [[LOOP:%.*]]
10 ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[LOOP]] ]
11 ; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[TMP1]], [[LIMIT:%.*]]
12 ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 10
13 ; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
14 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 [[TMP3]]
15 ; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP4]], align 4
16 ; CHECK-NEXT: [[TMP5]] = add i32 [[TMP1]], 16
17 ; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]]
19 ; CHECK-NEXT: ret void
22 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0
23 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer
24 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
25 %1 = trunc <16 x i64> %0 to <16 x i32>
29 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ]
30 %elt = extractelement <16 x i32> %2, i32 0
31 %end = icmp ult i32 %elt, %limit
33 %4 = sext i32 %elt to i64
34 %5 = getelementptr i32, i32* %ptr, i64 %4
36 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
37 br i1 %end, label %loop, label %ret
43 define void @copy(i64 %val, i32 %limit, i32 *%ptr) {
46 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32
47 ; CHECK-NEXT: br label [[LOOP:%.*]]
49 ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[LOOP]] ]
50 ; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[TMP1]], [[LIMIT:%.*]]
51 ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 10
52 ; CHECK-NEXT: [[TMP3:%.*]] = sext i32 [[TMP1]] to i64
53 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 [[TMP3]]
54 ; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP4]], align 4
55 ; CHECK-NEXT: [[TMP5]] = add i32 [[TMP1]], 16
56 ; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]]
58 ; CHECK-NEXT: ret void
61 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0
62 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer
63 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
64 %1 = trunc <16 x i64> %0 to <16 x i32>
68 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ]
69 %elt = extractelement <16 x i32> %2, i32 0
70 %eltcopy = extractelement <16 x i32> %2, i32 0
71 %end = icmp ult i32 %elt, %limit
72 %3 = add i32 10, %eltcopy
73 %4 = sext i32 %elt to i64
74 %5 = getelementptr i32, i32* %ptr, i64 %4
76 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
77 br i1 %end, label %loop, label %ret
83 define void @nocopy(i64 %val, i32 %limit, i32 *%ptr) {
84 ; CHECK-LABEL: @nocopy(
86 ; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[VAL:%.*]] to i32
87 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <16 x i32> undef, i32 [[TMP0]], i64 0
88 ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <16 x i32> [[TMP1]], <16 x i32> poison, <16 x i32> zeroinitializer
89 ; CHECK-NEXT: [[TMP3:%.*]] = add <16 x i32> [[TMP2]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
90 ; CHECK-NEXT: br label [[LOOP:%.*]]
92 ; CHECK-NEXT: [[TMP4:%.*]] = phi <16 x i32> [ [[TMP3]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[LOOP]] ]
93 ; CHECK-NEXT: [[ELT:%.*]] = extractelement <16 x i32> [[TMP4]], i64 0
94 ; CHECK-NEXT: [[ELTCOPY:%.*]] = extractelement <16 x i32> [[TMP4]], i64 1
95 ; CHECK-NEXT: [[END:%.*]] = icmp ult i32 [[ELT]], [[LIMIT:%.*]]
96 ; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[ELTCOPY]], 10
97 ; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[ELT]] to i64
98 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i32, i32* [[PTR:%.*]], i64 [[TMP6]]
99 ; CHECK-NEXT: store i32 [[TMP5]], i32* [[TMP7]], align 4
100 ; CHECK-NEXT: [[INC]] = add <16 x i32> [[TMP4]], <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
101 ; CHECK-NEXT: br i1 [[END]], label [[LOOP]], label [[RET:%.*]]
103 ; CHECK-NEXT: ret void
106 %tempvector = insertelement <16 x i64> poison, i64 %val, i32 0
107 %vector = shufflevector <16 x i64> %tempvector, <16 x i64> poison, <16 x i32> zeroinitializer
108 %0 = add <16 x i64> %vector, <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15>
109 %1 = trunc <16 x i64> %0 to <16 x i32>
113 %2 = phi <16 x i32> [ %1, %entry ], [ %inc, %loop ]
114 %elt = extractelement <16 x i32> %2, i32 0
115 %eltcopy = extractelement <16 x i32> %2, i32 1
116 %end = icmp ult i32 %elt, %limit
117 %3 = add i32 10, %eltcopy
118 %4 = sext i32 %elt to i64
119 %5 = getelementptr i32, i32* %ptr, i64 %4
120 store i32 %3, i32* %5
121 %inc = add <16 x i32> %2, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16>
122 br i1 %end, label %loop, label %ret
128 define i1 @g(<3 x i32> %input_2) {
131 ; CHECK-NEXT: [[TMP0:%.*]] = extractelement <3 x i32> [[INPUT_2:%.*]], i64 0
132 ; CHECK-NEXT: br label [[FOR_COND:%.*]]
134 ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP0]], [[ENTRY:%.*]] ], [ [[TMP4:%.*]], [[FOR_BODY:%.*]] ]
135 ; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ undef, [[ENTRY]] ], [ [[TMP3:%.*]], [[FOR_BODY]] ]
136 ; CHECK-NEXT: br i1 undef, label [[FOR_END:%.*]], label [[FOR_BODY]]
138 ; CHECK-NEXT: [[TMP3]] = add i32 [[TMP2]], -1
139 ; CHECK-NEXT: [[SUB44_ELT:%.*]] = sub i32 0, [[TMP2]]
140 ; CHECK-NEXT: [[TMP4]] = sdiv i32 [[TMP1]], [[SUB44_ELT]]
141 ; CHECK-NEXT: br label [[FOR_COND]]
143 ; CHECK-NEXT: [[TOBOOL313:%.*]] = icmp eq i32 [[TMP1]], 0
144 ; CHECK-NEXT: ret i1 [[TOBOOL313]]
150 %input_2.addr.0 = phi <3 x i32> [ %input_2, %entry ], [ %div45, %for.body ]
151 %input_1.addr.1 = phi <3 x i32> [ undef, %entry ], [ %dec43, %for.body ]
152 br i1 undef, label %for.end, label %for.body
155 %dec43 = add <3 x i32> %input_1.addr.1, <i32 -1, i32 -1, i32 -1>
156 %sub44 = sub <3 x i32> <i32 -1, i32 -1, i32 -1>, %dec43
157 %div45 = sdiv <3 x i32> %input_2.addr.0, %sub44
161 %0 = extractelement <3 x i32> %input_2.addr.0, i32 0
162 %.89 = select i1 false, i32 0, i32 %0
163 %tobool313 = icmp eq i32 %.89, 0