1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -o - -S -load-store-vectorizer -dce %s | FileCheck %s 3 4; Make sure LoadStoreVectorizer vectorizes the loads below. 5; In order to prove that the vectorization is safe, it tries to 6; match nested adds and find an expression that adds a constant 7; value to an existing index and the result doesn't overflow. 8 9target triple = "x86_64--" 10 11define void @ld_v4i8_add_nsw(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) { 12; CHECK-LABEL: @ld_v4i8_add_nsw( 13; CHECK-NEXT: bb: 14; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -1 15; CHECK-NEXT: [[TMP1:%.*]] = add nsw i32 [[V1:%.*]], [[TMP]] 16; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 17; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]] 18; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>* 19; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1 20; CHECK-NEXT: [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0 21; CHECK-NEXT: [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 22; CHECK-NEXT: [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 23; CHECK-NEXT: [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3 24; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 0 25; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 1 26; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 2 27; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 3 28; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 29; CHECK-NEXT: ret void 30; 31bb: 32 %tmp = add nsw i32 %v0, -1 33 %tmp1 = add nsw i32 %v1, %tmp 34 %tmp2 = sext i32 %tmp1 to i64 35 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 36 %tmp4 = load i8, i8* %tmp3, align 1 37 %tmp5 = add nsw i32 %v1, %v0 38 %tmp6 = sext i32 %tmp5 to i64 39 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 40 %tmp8 = load i8, i8* %tmp7, align 1 41 %tmp9 = add nsw i32 %v0, 1 42 %tmp10 = add nsw i32 %v1, %tmp9 43 %tmp11 = sext i32 %tmp10 to i64 44 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 45 %tmp13 = load i8, i8* %tmp12, align 1 46 %tmp14 = add nsw i32 %v0, 2 47 %tmp15 = add nsw i32 %v1, %tmp14 48 %tmp16 = sext i32 %tmp15 to i64 49 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 50 %tmp18 = load i8, i8* %tmp17, align 1 51 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 52 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 53 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 54 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 55 store <4 x i8> %tmp22, <4 x i8>* %dst 56 ret void 57} 58 59define void @ld_v4i8_add_nuw(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) { 60; CHECK-LABEL: @ld_v4i8_add_nuw( 61; CHECK-NEXT: bb: 62; CHECK-NEXT: [[TMP:%.*]] = add nuw i32 [[V0:%.*]], -1 63; CHECK-NEXT: [[TMP1:%.*]] = add nuw i32 [[V1:%.*]], [[TMP]] 64; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 65; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]] 66; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP3]] to <4 x i8>* 67; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1 68; CHECK-NEXT: [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0 69; CHECK-NEXT: [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 70; CHECK-NEXT: [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 71; CHECK-NEXT: [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3 72; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 0 73; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 1 74; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 2 75; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 3 76; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 77; CHECK-NEXT: ret void 78; 79bb: 80 %tmp = add nuw i32 %v0, -1 81 %tmp1 = add nuw i32 %v1, %tmp 82 %tmp2 = zext i32 %tmp1 to i64 83 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 84 %tmp4 = load i8, i8* %tmp3, align 1 85 %tmp5 = add nuw i32 %v1, %v0 86 %tmp6 = zext i32 %tmp5 to i64 87 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 88 %tmp8 = load i8, i8* %tmp7, align 1 89 %tmp9 = add nuw i32 %v0, 1 90 %tmp10 = add nuw i32 %v1, %tmp9 91 %tmp11 = zext i32 %tmp10 to i64 92 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 93 %tmp13 = load i8, i8* %tmp12, align 1 94 %tmp14 = add nuw i32 %v0, 2 95 %tmp15 = add nuw i32 %v1, %tmp14 96 %tmp16 = zext i32 %tmp15 to i64 97 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 98 %tmp18 = load i8, i8* %tmp17, align 1 99 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 100 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 101 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 102 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 103 store <4 x i8> %tmp22, <4 x i8>* %dst 104 ret void 105} 106 107define void @ld_v4i8_add_known_bits(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) { 108; CHECK-LABEL: @ld_v4i8_add_known_bits( 109; CHECK-NEXT: bb: 110; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 111; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 4 112; CHECK-NEXT: [[TMP:%.*]] = add i32 [[V0]], -1 113; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[V1]], [[TMP]] 114; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 115; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]] 116; CHECK-NEXT: [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1 117; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 118; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 119; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]] 120; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <3 x i8>* 121; CHECK-NEXT: [[TMP1:%.*]] = load <3 x i8>, <3 x i8>* [[TMP0]], align 1 122; CHECK-NEXT: [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0 123; CHECK-NEXT: [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1 124; CHECK-NEXT: [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2 125; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0 126; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1 127; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2 128; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3 129; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 130; CHECK-NEXT: ret void 131; 132bb: 133 %v0 = mul i32 %ind0, 4 134 %v1 = mul i32 %ind1, 4 135 %tmp = add i32 %v0, -1 136 %tmp1 = add i32 %v1, %tmp 137 %tmp2 = sext i32 %tmp1 to i64 138 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 139 %tmp4 = load i8, i8* %tmp3, align 1 140 %tmp5 = add i32 %v1, %v0 141 %tmp6 = sext i32 %tmp5 to i64 142 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 143 %tmp8 = load i8, i8* %tmp7, align 1 144 %tmp9 = add i32 %v0, 1 145 %tmp10 = add i32 %v1, %tmp9 146 %tmp11 = sext i32 %tmp10 to i64 147 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 148 %tmp13 = load i8, i8* %tmp12, align 1 149 %tmp14 = add i32 %v0, 2 150 %tmp15 = add i32 %v1, %tmp14 151 %tmp16 = sext i32 %tmp15 to i64 152 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 153 %tmp18 = load i8, i8* %tmp17, align 1 154 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 155 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 156 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 157 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 158 store <4 x i8> %tmp22, <4 x i8>* %dst 159 ret void 160} 161 162define void @ld_v4i8_add_known_bits1(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) { 163; CHECK-LABEL: @ld_v4i8_add_known_bits1( 164; CHECK-NEXT: bb: 165; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 166; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 4 167; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 168; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 169; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 170; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>* 171; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1 172; CHECK-NEXT: [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0 173; CHECK-NEXT: [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 174; CHECK-NEXT: [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 175; CHECK-NEXT: [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3 176; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0 177; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1 178; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2 179; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3 180; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 181; CHECK-NEXT: ret void 182; 183bb: 184 %v0 = mul i32 %ind0, 4 185 %v1 = mul i32 %ind1, 4 186 %tmp = add i32 %v0, 3 187 %tmp1 = add i32 %v1, %tmp 188 %tmp2 = sext i32 %tmp1 to i64 189 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 190 %tmp4 = load i8, i8* %tmp3, align 1 191 %tmp5 = add i32 %v1, %v0 192 %tmp6 = sext i32 %tmp5 to i64 193 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 194 %tmp8 = load i8, i8* %tmp7, align 1 195 %tmp9 = add i32 %v0, 1 196 %tmp10 = add i32 %v1, %tmp9 197 %tmp11 = sext i32 %tmp10 to i64 198 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 199 %tmp13 = load i8, i8* %tmp12, align 1 200 %tmp14 = add i32 %v0, 2 201 %tmp15 = add i32 %v1, %tmp14 202 %tmp16 = sext i32 %tmp15 to i64 203 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 204 %tmp18 = load i8, i8* %tmp17, align 1 205 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 206 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 207 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 208 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 209 store <4 x i8> %tmp22, <4 x i8>* %dst 210 ret void 211} 212 213define void @ld_v4i8_add_known_bits_by_assume(i32 %ind0, i32 %ind1, i8* %src, <4 x i8>* %dst) { 214; CHECK-LABEL: @ld_v4i8_add_known_bits_by_assume( 215; CHECK-NEXT: bb: 216; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 3 217; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 3 218; CHECK-NEXT: [[AND_I:%.*]] = and i32 [[V0]], 3 219; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0 220; CHECK-NEXT: [[AND_I_1:%.*]] = and i32 [[V1]], 3 221; CHECK-NEXT: [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0 222; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I]]) 223; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I_1]]) 224; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 225; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 226; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 227; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>* 228; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1 229; CHECK-NEXT: [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0 230; CHECK-NEXT: [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 231; CHECK-NEXT: [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 232; CHECK-NEXT: [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3 233; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0 234; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1 235; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2 236; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3 237; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 238; CHECK-NEXT: ret void 239; 240bb: 241 %v0 = mul i32 %ind0, 3 242 %v1 = mul i32 %ind1, 3 243 %and.i = and i32 %v0, 3 244 %cmp.i = icmp eq i32 %and.i, 0 245 %and.i.1 = and i32 %v1, 3 246 %cmp.i.1 = icmp eq i32 %and.i.1, 0 247 call void @llvm.assume(i1 %cmp.i) 248 call void @llvm.assume(i1 %cmp.i.1) 249 %tmp = add i32 %v0, 3 250 %tmp1 = add i32 %v1, %tmp 251 %tmp2 = sext i32 %tmp1 to i64 252 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 253 %tmp4 = load i8, i8* %tmp3, align 1 254 %tmp5 = add i32 %v1, %v0 255 %tmp6 = sext i32 %tmp5 to i64 256 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 257 %tmp8 = load i8, i8* %tmp7, align 1 258 %tmp9 = add i32 %v0, 1 259 %tmp10 = add i32 %v1, %tmp9 260 %tmp11 = sext i32 %tmp10 to i64 261 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 262 %tmp13 = load i8, i8* %tmp12, align 1 263 %tmp14 = add i32 %v0, 2 264 %tmp15 = add i32 %v1, %tmp14 265 %tmp16 = sext i32 %tmp15 to i64 266 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 267 %tmp18 = load i8, i8* %tmp17, align 1 268 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 269 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 270 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 271 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 272 store <4 x i8> %tmp22, <4 x i8>* %dst 273 ret void 274} 275 276declare void @llvm.assume(i1) 277 278define void @ld_v4i8_add_assume_on_arg(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) { 279; CHECK-LABEL: @ld_v4i8_add_assume_on_arg( 280; CHECK-NEXT: bb: 281; CHECK-NEXT: [[AND_I:%.*]] = and i32 [[V0:%.*]], 3 282; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0 283; CHECK-NEXT: [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3 284; CHECK-NEXT: [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0 285; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I]]) 286; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I_1]]) 287; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[V0]], -1 288; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[V1]], [[TMP]] 289; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 290; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]] 291; CHECK-NEXT: [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1 292; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 293; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 294; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]] 295; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <3 x i8>* 296; CHECK-NEXT: [[TMP1:%.*]] = load <3 x i8>, <3 x i8>* [[TMP0]], align 1 297; CHECK-NEXT: [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0 298; CHECK-NEXT: [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1 299; CHECK-NEXT: [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2 300; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0 301; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1 302; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2 303; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3 304; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 305; CHECK-NEXT: ret void 306; 307bb: 308 %and.i = and i32 %v0, 3 309 %cmp.i = icmp eq i32 %and.i, 0 310 %and.i.1 = and i32 %v1, 3 311 %cmp.i.1 = icmp eq i32 %and.i.1, 0 312 call void @llvm.assume(i1 %cmp.i) 313 call void @llvm.assume(i1 %cmp.i.1) 314 %tmp = add nsw i32 %v0, -1 315 %tmp1 = add i32 %v1, %tmp 316 %tmp2 = sext i32 %tmp1 to i64 317 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 318 %tmp4 = load i8, i8* %tmp3, align 1 319 %tmp5 = add i32 %v1, %v0 320 %tmp6 = sext i32 %tmp5 to i64 321 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 322 %tmp8 = load i8, i8* %tmp7, align 1 323 %tmp9 = add nsw i32 %v0, 1 324 %tmp10 = add i32 %v1, %tmp9 325 %tmp11 = sext i32 %tmp10 to i64 326 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 327 %tmp13 = load i8, i8* %tmp12, align 1 328 %tmp14 = add nsw i32 %v0, 2 329 %tmp15 = add i32 %v1, %tmp14 330 %tmp16 = sext i32 %tmp15 to i64 331 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 332 %tmp18 = load i8, i8* %tmp17, align 1 333 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 334 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 335 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 336 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 337 store <4 x i8> %tmp22, <4 x i8>* %dst 338 ret void 339} 340 341define void @ld_v4i8_add_assume_on_arg1(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) { 342; CHECK-LABEL: @ld_v4i8_add_assume_on_arg1( 343; CHECK-NEXT: bb: 344; CHECK-NEXT: [[AND_I:%.*]] = and i32 [[V0:%.*]], 3 345; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0 346; CHECK-NEXT: [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3 347; CHECK-NEXT: [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0 348; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I]]) 349; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_I_1]]) 350; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 351; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 352; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 353; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <4 x i8>* 354; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, <4 x i8>* [[TMP0]], align 1 355; CHECK-NEXT: [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0 356; CHECK-NEXT: [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 357; CHECK-NEXT: [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 358; CHECK-NEXT: [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3 359; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0 360; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1 361; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2 362; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3 363; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 364; CHECK-NEXT: ret void 365; 366bb: 367 %and.i = and i32 %v0, 3 368 %cmp.i = icmp eq i32 %and.i, 0 369 %and.i.1 = and i32 %v1, 3 370 %cmp.i.1 = icmp eq i32 %and.i.1, 0 371 call void @llvm.assume(i1 %cmp.i) 372 call void @llvm.assume(i1 %cmp.i.1) 373 %tmp = add nsw i32 %v0, 3 374 %tmp1 = add i32 %v1, %tmp 375 %tmp2 = sext i32 %tmp1 to i64 376 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 377 %tmp4 = load i8, i8* %tmp3, align 1 378 %tmp5 = add i32 %v1, %v0 379 %tmp6 = sext i32 %tmp5 to i64 380 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 381 %tmp8 = load i8, i8* %tmp7, align 1 382 %tmp9 = add nsw i32 %v0, 1 383 %tmp10 = add i32 %v1, %tmp9 384 %tmp11 = sext i32 %tmp10 to i64 385 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 386 %tmp13 = load i8, i8* %tmp12, align 1 387 %tmp14 = add nsw i32 %v0, 2 388 %tmp15 = add i32 %v1, %tmp14 389 %tmp16 = sext i32 %tmp15 to i64 390 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 391 %tmp18 = load i8, i8* %tmp17, align 1 392 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 393 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 394 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 395 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 396 store <4 x i8> %tmp22, <4 x i8>* %dst 397 ret void 398} 399 400; Address computations are partly separated by control flow and with llvm.assume placed 401; in the second basic block 402 403define void @ld_v2i8_add_different_contexts(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) { 404; CHECK-LABEL: @ld_v2i8_add_different_contexts( 405; CHECK-NEXT: bb: 406; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 407; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 3 408; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 409; CHECK-NEXT: [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0 410; CHECK-NEXT: br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]] 411; CHECK: bb.loads: 412; CHECK-NEXT: call void @llvm.assume(i1 [[BIT_COND]]) 413; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 414; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 415; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>* 416; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1 417; CHECK-NEXT: [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0 418; CHECK-NEXT: [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1 419; CHECK-NEXT: [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0 420; CHECK-NEXT: [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1 421; CHECK-NEXT: store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]] 422; CHECK-NEXT: br label [[BB_SKIP]] 423; CHECK: bb.skip: 424; CHECK-NEXT: ret void 425; 426bb: 427 %v0 = mul i32 %ind0, 4 428 %v1 = mul i32 %ind1, 3 429 %tmp5 = add i32 %v1, %v0 430 %bit_cond = icmp eq i32 %v1, 0 431 br i1 %bit_cond, label %bb.loads, label %bb.skip 432 433bb.loads: 434 call void @llvm.assume(i1 %bit_cond) 435 %tmp = add nsw i32 %v0, 1 436 %tmp1 = add i32 %v1, %tmp 437 %tmp2 = sext i32 %tmp1 to i64 438 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 439 %tmp4 = load i8, i8* %tmp3, align 1 440 %tmp6 = sext i32 %tmp5 to i64 441 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 442 %tmp8 = load i8, i8* %tmp7, align 1 443 %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0 444 %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1 445 store <2 x i8> %tmp20, <2 x i8>* %dst 446 br label %bb.skip 447 448bb.skip: 449 ret void 450} 451 452; Same as ld_v2i8_add_different_contexts but with llvm.assume placed between loads 453 454define void @ld_v2i8_add_different_contexts1(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) { 455; CHECK-LABEL: @ld_v2i8_add_different_contexts1( 456; CHECK-NEXT: bb: 457; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 458; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 3 459; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 460; CHECK-NEXT: [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0 461; CHECK-NEXT: br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]] 462; CHECK: bb.loads: 463; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 464; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 465; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>* 466; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1 467; CHECK-NEXT: [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0 468; CHECK-NEXT: [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1 469; CHECK-NEXT: call void @llvm.assume(i1 [[BIT_COND]]) 470; CHECK-NEXT: [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0 471; CHECK-NEXT: [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1 472; CHECK-NEXT: store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]] 473; CHECK-NEXT: br label [[BB_SKIP]] 474; CHECK: bb.skip: 475; CHECK-NEXT: ret void 476; 477bb: 478 %v0 = mul i32 %ind0, 4 479 %v1 = mul i32 %ind1, 3 480 %tmp5 = add i32 %v1, %v0 481 %bit_cond = icmp eq i32 %v1, 0 482 br i1 %bit_cond, label %bb.loads, label %bb.skip 483 484bb.loads: 485 %tmp6 = sext i32 %tmp5 to i64 486 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 487 %tmp8 = load i8, i8* %tmp7, align 1 488 call void @llvm.assume(i1 %bit_cond) 489 %tmp = add nsw i32 %v0, 1 490 %tmp1 = add i32 %v1, %tmp 491 %tmp2 = sext i32 %tmp1 to i64 492 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 493 %tmp4 = load i8, i8* %tmp3, align 1 494 %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0 495 %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1 496 store <2 x i8> %tmp20, <2 x i8>* %dst 497 br label %bb.skip 498 499bb.skip: 500 ret void 501} 502 503; llvm.assume is placed between loads in a single basic block 504 505define void @ld_v2i8_add_context(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) { 506; CHECK-LABEL: @ld_v2i8_add_context( 507; CHECK-NEXT: bb: 508; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 509; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 3 510; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 511; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 512; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 513; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>* 514; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1 515; CHECK-NEXT: [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0 516; CHECK-NEXT: [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1 517; CHECK-NEXT: [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0 518; CHECK-NEXT: call void @llvm.assume(i1 [[BIT_COND]]) 519; CHECK-NEXT: [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0 520; CHECK-NEXT: [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1 521; CHECK-NEXT: store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]] 522; CHECK-NEXT: ret void 523; 524bb: 525 %v0 = mul i32 %ind0, 4 526 %v1 = mul i32 %ind1, 3 527 %tmp5 = add i32 %v1, %v0 528 %tmp6 = sext i32 %tmp5 to i64 529 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 530 %tmp8 = load i8, i8* %tmp7, align 1 531 %bit_cond = icmp eq i32 %tmp5, 0 532 call void @llvm.assume(i1 %bit_cond) 533 %tmp = add nsw i32 %v0, 1 534 %tmp1 = add i32 %v1, %tmp 535 %tmp2 = sext i32 %tmp1 to i64 536 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 537 %tmp4 = load i8, i8* %tmp3, align 1 538 %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0 539 %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1 540 store <2 x i8> %tmp20, <2 x i8>* %dst 541 ret void 542} 543 544; Placing llvm.assume after all the loads and stores in the basic block still works 545 546define void @ld_v2i8_add_context1(i32 %ind0, i32 %ind1, i8* %src, <2 x i8>* %dst) { 547; CHECK-LABEL: @ld_v2i8_add_context1( 548; CHECK-NEXT: bb: 549; CHECK-NEXT: [[V0:%.*]] = mul i32 [[IND0:%.*]], 4 550; CHECK-NEXT: [[V1:%.*]] = mul i32 [[IND1:%.*]], 3 551; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 552; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 553; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP6]] 554; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[TMP7]] to <2 x i8>* 555; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i8>, <2 x i8>* [[TMP0]], align 1 556; CHECK-NEXT: [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0 557; CHECK-NEXT: [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1 558; CHECK-NEXT: [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0 559; CHECK-NEXT: [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1 560; CHECK-NEXT: store <2 x i8> [[TMP20]], <2 x i8>* [[DST:%.*]] 561; CHECK-NEXT: [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0 562; CHECK-NEXT: call void @llvm.assume(i1 [[BIT_COND]]) 563; CHECK-NEXT: ret void 564; 565bb: 566 %v0 = mul i32 %ind0, 4 567 %v1 = mul i32 %ind1, 3 568 %tmp5 = add i32 %v1, %v0 569 %tmp6 = sext i32 %tmp5 to i64 570 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 571 %tmp8 = load i8, i8* %tmp7, align 1 572 %tmp = add nsw i32 %v0, 1 573 %tmp1 = add i32 %v1, %tmp 574 %tmp2 = sext i32 %tmp1 to i64 575 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 576 %tmp4 = load i8, i8* %tmp3, align 1 577 %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0 578 %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1 579 store <2 x i8> %tmp20, <2 x i8>* %dst 580 %bit_cond = icmp eq i32 %tmp5, 0 581 call void @llvm.assume(i1 %bit_cond) 582 ret void 583} 584 585; Make sure we don't vectorize the loads below because the source of 586; sext instructions doesn't have the nsw flag or known bits allowing 587; to apply the vectorization. 588 589define void @ld_v4i8_add_not_safe(i32 %v0, i32 %v1, i8* %src, <4 x i8>* %dst) { 590; CHECK-LABEL: @ld_v4i8_add_not_safe( 591; CHECK-NEXT: bb: 592; CHECK-NEXT: [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -1 593; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[V1:%.*]], [[TMP]] 594; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 595; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[SRC:%.*]], i64 [[TMP2]] 596; CHECK-NEXT: [[TMP4:%.*]] = load i8, i8* [[TMP3]], align 1 597; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[V1]], [[V0]] 598; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[TMP5]] to i64 599; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP6]] 600; CHECK-NEXT: [[TMP8:%.*]] = load i8, i8* [[TMP7]], align 1 601; CHECK-NEXT: [[TMP9:%.*]] = add nsw i32 [[V0]], 1 602; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[V1]], [[TMP9]] 603; CHECK-NEXT: [[TMP11:%.*]] = sext i32 [[TMP10]] to i64 604; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP11]] 605; CHECK-NEXT: [[TMP13:%.*]] = load i8, i8* [[TMP12]], align 1 606; CHECK-NEXT: [[TMP14:%.*]] = add nsw i32 [[V0]], 2 607; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[V1]], [[TMP14]] 608; CHECK-NEXT: [[TMP16:%.*]] = sext i32 [[TMP15]] to i64 609; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i8, i8* [[SRC]], i64 [[TMP16]] 610; CHECK-NEXT: [[TMP18:%.*]] = load i8, i8* [[TMP17]], align 1 611; CHECK-NEXT: [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0 612; CHECK-NEXT: [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP8]], i32 1 613; CHECK-NEXT: [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP13]], i32 2 614; CHECK-NEXT: [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP18]], i32 3 615; CHECK-NEXT: store <4 x i8> [[TMP22]], <4 x i8>* [[DST:%.*]] 616; CHECK-NEXT: ret void 617; 618bb: 619 %tmp = add nsw i32 %v0, -1 620 %tmp1 = add i32 %v1, %tmp 621 %tmp2 = sext i32 %tmp1 to i64 622 %tmp3 = getelementptr inbounds i8, i8* %src, i64 %tmp2 623 %tmp4 = load i8, i8* %tmp3, align 1 624 %tmp5 = add i32 %v1, %v0 625 %tmp6 = sext i32 %tmp5 to i64 626 %tmp7 = getelementptr inbounds i8, i8* %src, i64 %tmp6 627 %tmp8 = load i8, i8* %tmp7, align 1 628 %tmp9 = add nsw i32 %v0, 1 629 %tmp10 = add i32 %v1, %tmp9 630 %tmp11 = sext i32 %tmp10 to i64 631 %tmp12 = getelementptr inbounds i8, i8* %src, i64 %tmp11 632 %tmp13 = load i8, i8* %tmp12, align 1 633 %tmp14 = add nsw i32 %v0, 2 634 %tmp15 = add i32 %v1, %tmp14 635 %tmp16 = sext i32 %tmp15 to i64 636 %tmp17 = getelementptr inbounds i8, i8* %src, i64 %tmp16 637 %tmp18 = load i8, i8* %tmp17, align 1 638 %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0 639 %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1 640 %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2 641 %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3 642 store <4 x i8> %tmp22, <4 x i8>* %dst 643 ret void 644} 645