brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.1 KiB · cf575ce Raw
635 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -o - -S -passes=load-store-vectorizer,dce %s | FileCheck %s3 4; Make sure LoadStoreVectorizer vectorizes the loads below.5; In order to prove that the vectorization is safe, it tries to6; match nested adds and find an expression that adds a constant7; 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, ptr %src, ptr %dst) {12; CHECK-LABEL: @ld_v4i8_add_nsw(13; CHECK-NEXT:  bb:14; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -115; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[V1:%.*]], [[TMP]]16; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i6417; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP2]]18; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, ptr [[TMP3]], align 119; CHECK-NEXT:    [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 020; CHECK-NEXT:    [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 121; CHECK-NEXT:    [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 222; CHECK-NEXT:    [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 323; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 024; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 125; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 226; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 327; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]28; CHECK-NEXT:    ret void29;30bb:31  %tmp = add nsw i32 %v0, -132  %tmp1 = add nsw i32 %v1, %tmp33  %tmp2 = sext i32 %tmp1 to i6434  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp235  %tmp4 = load i8, ptr %tmp3, align 136  %tmp5 = add nsw i32 %v1, %v037  %tmp6 = sext i32 %tmp5 to i6438  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp639  %tmp8 = load i8, ptr %tmp7, align 140  %tmp9 = add nsw i32 %v0, 141  %tmp10 = add nsw i32 %v1, %tmp942  %tmp11 = sext i32 %tmp10 to i6443  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp1144  %tmp13 = load i8, ptr %tmp12, align 145  %tmp14 = add nsw i32 %v0, 246  %tmp15 = add nsw i32 %v1, %tmp1447  %tmp16 = sext i32 %tmp15 to i6448  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp1649  %tmp18 = load i8, ptr %tmp17, align 150  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 051  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 152  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 253  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 354  store <4 x i8> %tmp22, ptr %dst55  ret void56}57 58; Apply different operand orders for the nested add sequences59define void @ld_v4i8_add_nsw_operand_orders(i32 %v0, i32 %v1, ptr %src, ptr %dst) {60; CHECK-LABEL: @ld_v4i8_add_nsw_operand_orders(61; CHECK-NEXT:  bb:62; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -163; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i32 [[V1:%.*]], [[TMP]]64; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i6465; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP2]]66; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, ptr [[TMP3]], align 167; CHECK-NEXT:    [[TMP41:%.*]] = extractelement <4 x i8> [[TMP1]], i32 068; CHECK-NEXT:    [[TMP82:%.*]] = extractelement <4 x i8> [[TMP1]], i32 169; CHECK-NEXT:    [[TMP133:%.*]] = extractelement <4 x i8> [[TMP1]], i32 270; CHECK-NEXT:    [[TMP184:%.*]] = extractelement <4 x i8> [[TMP1]], i32 371; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP41]], i32 072; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP82]], i32 173; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP133]], i32 274; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP184]], i32 375; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]76; CHECK-NEXT:    ret void77;78bb:79  %tmp = add nsw i32 %v0, -180  %tmp1 = add nsw i32 %v1, %tmp81  %tmp2 = sext i32 %tmp1 to i6482  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp283  %tmp4 = load i8, ptr %tmp3, align 184  %tmp5 = add nsw i32 %v0, %v185  %tmp6 = sext i32 %tmp5 to i6486  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp687  %tmp8 = load i8, ptr %tmp7, align 188  %tmp9 = add nsw i32 %v0, 189  %tmp10 = add nsw i32 %tmp9, %v190  %tmp11 = sext i32 %tmp10 to i6491  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp1192  %tmp13 = load i8, ptr %tmp12, align 193  %tmp14 = add nsw i32 %v0, 294  %tmp15 = add nsw i32 %v1, %tmp1495  %tmp16 = sext i32 %tmp15 to i6496  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp1697  %tmp18 = load i8, ptr %tmp17, align 198  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 099  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1100  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2101  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3102  store <4 x i8> %tmp22, ptr %dst103  ret void104}105 106define void @ld_v4i8_add_known_bits(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {107; CHECK-LABEL: @ld_v4i8_add_known_bits(108; CHECK-NEXT:  bb:109; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4110; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 4111; CHECK-NEXT:    [[TMP:%.*]] = add i32 [[V0]], -1112; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1]], [[TMP]]113; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64114; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP2]]115; CHECK-NEXT:    [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1116; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]117; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64118; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[TMP6]]119; CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i8>, ptr [[TMP7]], align 1120; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0121; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1122; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2123; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0124; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1125; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2126; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3127; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]128; CHECK-NEXT:    ret void129;130bb:131  %v0 = mul i32 %ind0, 4132  %v1 = mul i32 %ind1, 4133  %tmp = add i32 %v0, -1134  %tmp1 = add i32 %v1, %tmp135  %tmp2 = sext i32 %tmp1 to i64136  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2137  %tmp4 = load i8, ptr %tmp3, align 1138  %tmp5 = add i32 %v1, %v0139  %tmp6 = sext i32 %tmp5 to i64140  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6141  %tmp8 = load i8, ptr %tmp7, align 1142  %tmp9 = add i32 %v0, 1143  %tmp10 = add i32 %v1, %tmp9144  %tmp11 = sext i32 %tmp10 to i64145  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11146  %tmp13 = load i8, ptr %tmp12, align 1147  %tmp14 = add i32 %v0, 2148  %tmp15 = add i32 %v1, %tmp14149  %tmp16 = sext i32 %tmp15 to i64150  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16151  %tmp18 = load i8, ptr %tmp17, align 1152  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0153  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1154  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2155  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3156  store <4 x i8> %tmp22, ptr %dst157  ret void158}159 160define void @ld_v4i8_add_known_bits1(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {161; CHECK-LABEL: @ld_v4i8_add_known_bits1(162; CHECK-NEXT:  bb:163; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4164; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 4165; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]166; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64167; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]168; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1169; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0170; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1171; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2172; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3173; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0174; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1175; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2176; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3177; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]178; CHECK-NEXT:    ret void179;180bb:181  %v0 = mul i32 %ind0, 4182  %v1 = mul i32 %ind1, 4183  %tmp = add i32 %v0, 3184  %tmp1 = add i32 %v1, %tmp185  %tmp2 = sext i32 %tmp1 to i64186  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2187  %tmp4 = load i8, ptr %tmp3, align 1188  %tmp5 = add i32 %v1, %v0189  %tmp6 = sext i32 %tmp5 to i64190  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6191  %tmp8 = load i8, ptr %tmp7, align 1192  %tmp9 = add i32 %v0, 1193  %tmp10 = add i32 %v1, %tmp9194  %tmp11 = sext i32 %tmp10 to i64195  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11196  %tmp13 = load i8, ptr %tmp12, align 1197  %tmp14 = add i32 %v0, 2198  %tmp15 = add i32 %v1, %tmp14199  %tmp16 = sext i32 %tmp15 to i64200  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16201  %tmp18 = load i8, ptr %tmp17, align 1202  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0203  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1204  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2205  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3206  store <4 x i8> %tmp22, ptr %dst207  ret void208}209 210define void @ld_v4i8_add_known_bits_by_assume(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {211; CHECK-LABEL: @ld_v4i8_add_known_bits_by_assume(212; CHECK-NEXT:  bb:213; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 3214; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3215; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0]], 3216; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0217; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1]], 3218; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0219; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])220; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])221; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]222; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64223; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]224; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1225; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0226; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1227; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2228; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3229; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0230; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1231; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2232; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3233; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]234; CHECK-NEXT:    ret void235;236bb:237  %v0 = mul i32 %ind0, 3238  %v1 = mul i32 %ind1, 3239  %and.i = and i32 %v0, 3240  %cmp.i = icmp eq i32 %and.i, 0241  %and.i.1 = and i32 %v1, 3242  %cmp.i.1 = icmp eq i32 %and.i.1, 0243  call void @llvm.assume(i1 %cmp.i)244  call void @llvm.assume(i1 %cmp.i.1)245  %tmp = add i32 %v0, 3246  %tmp1 = add i32 %v1, %tmp247  %tmp2 = sext i32 %tmp1 to i64248  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2249  %tmp4 = load i8, ptr %tmp3, align 1250  %tmp5 = add i32 %v1, %v0251  %tmp6 = sext i32 %tmp5 to i64252  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6253  %tmp8 = load i8, ptr %tmp7, align 1254  %tmp9 = add i32 %v0, 1255  %tmp10 = add i32 %v1, %tmp9256  %tmp11 = sext i32 %tmp10 to i64257  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11258  %tmp13 = load i8, ptr %tmp12, align 1259  %tmp14 = add i32 %v0, 2260  %tmp15 = add i32 %v1, %tmp14261  %tmp16 = sext i32 %tmp15 to i64262  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16263  %tmp18 = load i8, ptr %tmp17, align 1264  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0265  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1266  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2267  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3268  store <4 x i8> %tmp22, ptr %dst269  ret void270}271 272declare void @llvm.assume(i1)273 274define void @ld_v4i8_add_assume_on_arg(i32 %v0, i32 %v1, ptr %src, ptr %dst) {275; CHECK-LABEL: @ld_v4i8_add_assume_on_arg(276; CHECK-NEXT:  bb:277; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0:%.*]], 3278; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0279; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3280; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0281; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])282; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])283; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0]], -1284; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1]], [[TMP]]285; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64286; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP2]]287; CHECK-NEXT:    [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1288; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]289; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64290; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[TMP6]]291; CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i8>, ptr [[TMP7]], align 1292; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <3 x i8> [[TMP1]], i32 0293; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <3 x i8> [[TMP1]], i32 1294; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <3 x i8> [[TMP1]], i32 2295; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0296; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1297; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2298; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3299; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]300; CHECK-NEXT:    ret void301;302bb:303  %and.i = and i32 %v0, 3304  %cmp.i = icmp eq i32 %and.i, 0305  %and.i.1 = and i32 %v1, 3306  %cmp.i.1 = icmp eq i32 %and.i.1, 0307  call void @llvm.assume(i1 %cmp.i)308  call void @llvm.assume(i1 %cmp.i.1)309  %tmp = add nsw i32 %v0, -1310  %tmp1 = add i32 %v1, %tmp311  %tmp2 = sext i32 %tmp1 to i64312  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2313  %tmp4 = load i8, ptr %tmp3, align 1314  %tmp5 = add i32 %v1, %v0315  %tmp6 = sext i32 %tmp5 to i64316  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6317  %tmp8 = load i8, ptr %tmp7, align 1318  %tmp9 = add nsw i32 %v0, 1319  %tmp10 = add i32 %v1, %tmp9320  %tmp11 = sext i32 %tmp10 to i64321  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11322  %tmp13 = load i8, ptr %tmp12, align 1323  %tmp14 = add nsw i32 %v0, 2324  %tmp15 = add i32 %v1, %tmp14325  %tmp16 = sext i32 %tmp15 to i64326  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16327  %tmp18 = load i8, ptr %tmp17, align 1328  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0329  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1330  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2331  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3332  store <4 x i8> %tmp22, ptr %dst333  ret void334}335 336define void @ld_v4i8_add_assume_on_arg1(i32 %v0, i32 %v1, ptr %src, ptr %dst) {337; CHECK-LABEL: @ld_v4i8_add_assume_on_arg1(338; CHECK-NEXT:  bb:339; CHECK-NEXT:    [[AND_I:%.*]] = and i32 [[V0:%.*]], 3340; CHECK-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[AND_I]], 0341; CHECK-NEXT:    [[AND_I_1:%.*]] = and i32 [[V1:%.*]], 3342; CHECK-NEXT:    [[CMP_I_1:%.*]] = icmp eq i32 [[AND_I_1]], 0343; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I]])344; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_I_1]])345; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]346; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64347; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]348; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x i8>, ptr [[TMP7]], align 1349; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <4 x i8> [[TMP1]], i32 0350; CHECK-NEXT:    [[TMP132:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1351; CHECK-NEXT:    [[TMP183:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2352; CHECK-NEXT:    [[TMP44:%.*]] = extractelement <4 x i8> [[TMP1]], i32 3353; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP44]], i32 0354; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP81]], i32 1355; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP132]], i32 2356; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP183]], i32 3357; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]358; CHECK-NEXT:    ret void359;360bb:361  %and.i = and i32 %v0, 3362  %cmp.i = icmp eq i32 %and.i, 0363  %and.i.1 = and i32 %v1, 3364  %cmp.i.1 = icmp eq i32 %and.i.1, 0365  call void @llvm.assume(i1 %cmp.i)366  call void @llvm.assume(i1 %cmp.i.1)367  %tmp = add nsw i32 %v0, 3368  %tmp1 = add i32 %v1, %tmp369  %tmp2 = sext i32 %tmp1 to i64370  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2371  %tmp4 = load i8, ptr %tmp3, align 1372  %tmp5 = add i32 %v1, %v0373  %tmp6 = sext i32 %tmp5 to i64374  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6375  %tmp8 = load i8, ptr %tmp7, align 1376  %tmp9 = add nsw i32 %v0, 1377  %tmp10 = add i32 %v1, %tmp9378  %tmp11 = sext i32 %tmp10 to i64379  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11380  %tmp13 = load i8, ptr %tmp12, align 1381  %tmp14 = add nsw i32 %v0, 2382  %tmp15 = add i32 %v1, %tmp14383  %tmp16 = sext i32 %tmp15 to i64384  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16385  %tmp18 = load i8, ptr %tmp17, align 1386  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0387  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1388  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2389  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3390  store <4 x i8> %tmp22, ptr %dst391  ret void392}393 394; Address computations are partly separated by control flow and with llvm.assume placed395; in the second basic block396 397define void @ld_v2i8_add_different_contexts(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {398; CHECK-LABEL: @ld_v2i8_add_different_contexts(399; CHECK-NEXT:  bb:400; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4401; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3402; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]403; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0404; CHECK-NEXT:    br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]]405; CHECK:       bb.loads:406; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])407; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64408; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]409; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, ptr [[TMP7]], align 1410; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0411; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1412; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0413; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1414; CHECK-NEXT:    store <2 x i8> [[TMP20]], ptr [[DST:%.*]]415; CHECK-NEXT:    br label [[BB_SKIP]]416; CHECK:       bb.skip:417; CHECK-NEXT:    ret void418;419bb:420  %v0 = mul i32 %ind0, 4421  %v1 = mul i32 %ind1, 3422  %tmp5 = add i32 %v1, %v0423  %bit_cond = icmp eq i32 %v1, 0424  br i1 %bit_cond, label %bb.loads, label %bb.skip425 426bb.loads:427  call void @llvm.assume(i1 %bit_cond)428  %tmp = add nsw i32 %v0, 1429  %tmp1 = add i32 %v1, %tmp430  %tmp2 = sext i32 %tmp1 to i64431  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2432  %tmp4 = load i8, ptr %tmp3, align 1433  %tmp6 = sext i32 %tmp5 to i64434  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6435  %tmp8 = load i8, ptr %tmp7, align 1436  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0437  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1438  store <2 x i8> %tmp20, ptr %dst439  br label %bb.skip440 441bb.skip:442  ret void443}444 445; Same as ld_v2i8_add_different_contexts but with llvm.assume placed between loads446 447define void @ld_v2i8_add_different_contexts1(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {448; CHECK-LABEL: @ld_v2i8_add_different_contexts1(449; CHECK-NEXT:  bb:450; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4451; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3452; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]453; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[V1]], 0454; CHECK-NEXT:    br i1 [[BIT_COND]], label [[BB_LOADS:%.*]], label [[BB_SKIP:%.*]]455; CHECK:       bb.loads:456; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64457; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]458; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, ptr [[TMP7]], align 1459; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0460; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1461; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])462; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0463; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1464; CHECK-NEXT:    store <2 x i8> [[TMP20]], ptr [[DST:%.*]]465; CHECK-NEXT:    br label [[BB_SKIP]]466; CHECK:       bb.skip:467; CHECK-NEXT:    ret void468;469bb:470  %v0 = mul i32 %ind0, 4471  %v1 = mul i32 %ind1, 3472  %tmp5 = add i32 %v1, %v0473  %bit_cond = icmp eq i32 %v1, 0474  br i1 %bit_cond, label %bb.loads, label %bb.skip475 476bb.loads:477  %tmp6 = sext i32 %tmp5 to i64478  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6479  %tmp8 = load i8, ptr %tmp7, align 1480  call void @llvm.assume(i1 %bit_cond)481  %tmp = add nsw i32 %v0, 1482  %tmp1 = add i32 %v1, %tmp483  %tmp2 = sext i32 %tmp1 to i64484  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2485  %tmp4 = load i8, ptr %tmp3, align 1486  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0487  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1488  store <2 x i8> %tmp20, ptr %dst489  br label %bb.skip490 491bb.skip:492  ret void493}494 495; llvm.assume is placed between loads in a single basic block496 497define void @ld_v2i8_add_context(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {498; CHECK-LABEL: @ld_v2i8_add_context(499; CHECK-NEXT:  bb:500; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4501; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3502; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]503; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64504; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]505; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, ptr [[TMP7]], align 1506; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0507; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1508; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0509; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])510; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0511; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1512; CHECK-NEXT:    store <2 x i8> [[TMP20]], ptr [[DST:%.*]]513; CHECK-NEXT:    ret void514;515bb:516  %v0 = mul i32 %ind0, 4517  %v1 = mul i32 %ind1, 3518  %tmp5 = add i32 %v1, %v0519  %tmp6 = sext i32 %tmp5 to i64520  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6521  %tmp8 = load i8, ptr %tmp7, align 1522  %bit_cond = icmp eq i32 %tmp5, 0523  call void @llvm.assume(i1 %bit_cond)524  %tmp = add nsw i32 %v0, 1525  %tmp1 = add i32 %v1, %tmp526  %tmp2 = sext i32 %tmp1 to i64527  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2528  %tmp4 = load i8, ptr %tmp3, align 1529  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0530  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1531  store <2 x i8> %tmp20, ptr %dst532  ret void533}534 535; Placing llvm.assume after all the loads and stores in the basic block still works536 537define void @ld_v2i8_add_context1(i32 %ind0, i32 %ind1, ptr %src, ptr %dst) {538; CHECK-LABEL: @ld_v2i8_add_context1(539; CHECK-NEXT:  bb:540; CHECK-NEXT:    [[V0:%.*]] = mul i32 [[IND0:%.*]], 4541; CHECK-NEXT:    [[V1:%.*]] = mul i32 [[IND1:%.*]], 3542; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]543; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64544; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP6]]545; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i8>, ptr [[TMP7]], align 1546; CHECK-NEXT:    [[TMP81:%.*]] = extractelement <2 x i8> [[TMP1]], i32 0547; CHECK-NEXT:    [[TMP42:%.*]] = extractelement <2 x i8> [[TMP1]], i32 1548; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <2 x i8> undef, i8 [[TMP42]], i32 0549; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <2 x i8> [[TMP19]], i8 [[TMP81]], i32 1550; CHECK-NEXT:    store <2 x i8> [[TMP20]], ptr [[DST:%.*]]551; CHECK-NEXT:    [[BIT_COND:%.*]] = icmp eq i32 [[TMP5]], 0552; CHECK-NEXT:    call void @llvm.assume(i1 [[BIT_COND]])553; CHECK-NEXT:    ret void554;555bb:556  %v0 = mul i32 %ind0, 4557  %v1 = mul i32 %ind1, 3558  %tmp5 = add i32 %v1, %v0559  %tmp6 = sext i32 %tmp5 to i64560  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6561  %tmp8 = load i8, ptr %tmp7, align 1562  %tmp = add nsw i32 %v0, 1563  %tmp1 = add i32 %v1, %tmp564  %tmp2 = sext i32 %tmp1 to i64565  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2566  %tmp4 = load i8, ptr %tmp3, align 1567  %tmp19 = insertelement <2 x i8> undef, i8 %tmp4, i32 0568  %tmp20 = insertelement <2 x i8> %tmp19, i8 %tmp8, i32 1569  store <2 x i8> %tmp20, ptr %dst570  %bit_cond = icmp eq i32 %tmp5, 0571  call void @llvm.assume(i1 %bit_cond)572  ret void573}574 575; Make sure we don't vectorize the loads below because the source of576; sext instructions doesn't have the nsw flag or known bits allowing577; to apply the vectorization.578 579define void @ld_v4i8_add_not_safe(i32 %v0, i32 %v1, ptr %src, ptr %dst) {580; CHECK-LABEL: @ld_v4i8_add_not_safe(581; CHECK-NEXT:  bb:582; CHECK-NEXT:    [[TMP:%.*]] = add nsw i32 [[V0:%.*]], -1583; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[V1:%.*]], [[TMP]]584; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[TMP1]] to i64585; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP2]]586; CHECK-NEXT:    [[TMP4:%.*]] = load i8, ptr [[TMP3]], align 1587; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[V1]], [[V0]]588; CHECK-NEXT:    [[TMP6:%.*]] = sext i32 [[TMP5]] to i64589; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[TMP6]]590; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[TMP7]], align 1591; CHECK-NEXT:    [[TMP9:%.*]] = add nsw i32 [[V0]], 1592; CHECK-NEXT:    [[TMP10:%.*]] = add i32 [[V1]], [[TMP9]]593; CHECK-NEXT:    [[TMP11:%.*]] = sext i32 [[TMP10]] to i64594; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[TMP11]]595; CHECK-NEXT:    [[TMP13:%.*]] = load i8, ptr [[TMP12]], align 1596; CHECK-NEXT:    [[TMP14:%.*]] = add nsw i32 [[V0]], 2597; CHECK-NEXT:    [[TMP15:%.*]] = add i32 [[V1]], [[TMP14]]598; CHECK-NEXT:    [[TMP16:%.*]] = sext i32 [[TMP15]] to i64599; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[TMP16]]600; CHECK-NEXT:    [[TMP18:%.*]] = load i8, ptr [[TMP17]], align 1601; CHECK-NEXT:    [[TMP19:%.*]] = insertelement <4 x i8> undef, i8 [[TMP4]], i32 0602; CHECK-NEXT:    [[TMP20:%.*]] = insertelement <4 x i8> [[TMP19]], i8 [[TMP8]], i32 1603; CHECK-NEXT:    [[TMP21:%.*]] = insertelement <4 x i8> [[TMP20]], i8 [[TMP13]], i32 2604; CHECK-NEXT:    [[TMP22:%.*]] = insertelement <4 x i8> [[TMP21]], i8 [[TMP18]], i32 3605; CHECK-NEXT:    store <4 x i8> [[TMP22]], ptr [[DST:%.*]]606; CHECK-NEXT:    ret void607;608bb:609  %tmp = add nsw i32 %v0, -1610  %tmp1 = add i32 %v1, %tmp611  %tmp2 = sext i32 %tmp1 to i64612  %tmp3 = getelementptr inbounds i8, ptr %src, i64 %tmp2613  %tmp4 = load i8, ptr %tmp3, align 1614  %tmp5 = add i32 %v1, %v0615  %tmp6 = sext i32 %tmp5 to i64616  %tmp7 = getelementptr inbounds i8, ptr %src, i64 %tmp6617  %tmp8 = load i8, ptr %tmp7, align 1618  %tmp9 = add nsw i32 %v0, 1619  %tmp10 = add i32 %v1, %tmp9620  %tmp11 = sext i32 %tmp10 to i64621  %tmp12 = getelementptr inbounds i8, ptr %src, i64 %tmp11622  %tmp13 = load i8, ptr %tmp12, align 1623  %tmp14 = add nsw i32 %v0, 2624  %tmp15 = add i32 %v1, %tmp14625  %tmp16 = sext i32 %tmp15 to i64626  %tmp17 = getelementptr inbounds i8, ptr %src, i64 %tmp16627  %tmp18 = load i8, ptr %tmp17, align 1628  %tmp19 = insertelement <4 x i8> undef, i8 %tmp4, i32 0629  %tmp20 = insertelement <4 x i8> %tmp19, i8 %tmp8, i32 1630  %tmp21 = insertelement <4 x i8> %tmp20, i8 %tmp13, i32 2631  %tmp22 = insertelement <4 x i8> %tmp21, i8 %tmp18, i32 3632  store <4 x i8> %tmp22, ptr %dst633  ret void634}635