; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -mtriple=thumbv7-unknown-linux-gnueabihf -arm-parallel-dsp -dce %s -S -o - | FileCheck %s
define i32 @first_mul_invalid(ptr nocapture readonly %in, ptr nocapture readonly %b) {
; CHECK-LABEL: @first_mul_invalid(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[IN:%.*]], align 2
; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[B:%.*]], align 2
; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[TMP1]] to i32
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @bar(i32 [[CONV]], i32 [[CONV2]])
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -1
; CHECK-NEXT: [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX3]], align 2
; CHECK-NEXT: [[CONV4:%.*]] = sext i16 [[TMP2]] to i32
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 1
; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[ARRAYIDX5]], align 2
; CHECK-NEXT: [[CONV6:%.*]] = sext i16 [[TMP3]] to i32
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[CONV6]], [[CONV4]]
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[CALL]]
; CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -3
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX13]], align 2
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 2
; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX9]], align 2
; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP5]], i32 [[TMP7]], i32 [[ADD]])
; CHECK-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -5
; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX25]], align 2
; CHECK-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 4
; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX21]], align 2
; CHECK-NEXT: [[TMP13:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP10]], i32 [[TMP12]], i32 [[TMP8]])
; CHECK-NEXT: ret i32 [[TMP13]]
;
entry:
%0 = load i16, ptr %in, align 2
%conv = sext i16 %0 to i32
%1 = load i16, ptr %b, align 2
%conv2 = sext i16 %1 to i32
%call = tail call i32 @bar(i32 %conv, i32 %conv2)
%arrayidx3 = getelementptr inbounds i16, ptr %in, i32 -1
%2 = load i16, ptr %arrayidx3, align 2
%conv4 = sext i16 %2 to i32
%arrayidx5 = getelementptr inbounds i16, ptr %b, i32 1
%3 = load i16, ptr %arrayidx5, align 2
%conv6 = sext i16 %3 to i32
%mul = mul nsw i32 %conv6, %conv4
%add = add i32 %mul, %call
%arrayidx7 = getelementptr inbounds i16, ptr %in, i32 -2
%4 = load i16, ptr %arrayidx7, align 2
%conv8 = sext i16 %4 to i32
%arrayidx9 = getelementptr inbounds i16, ptr %b, i32 2
%5 = load i16, ptr %arrayidx9, align 2
%conv10 = sext i16 %5 to i32
%mul11 = mul nsw i32 %conv10, %conv8
%add12 = add i32 %add, %mul11
%arrayidx13 = getelementptr inbounds i16, ptr %in, i32 -3
%6 = load i16, ptr %arrayidx13, align 2
%conv14 = sext i16 %6 to i32
%arrayidx15 = getelementptr inbounds i16, ptr %b, i32 3
%7 = load i16, ptr %arrayidx15, align 2
%conv16 = sext i16 %7 to i32
%mul17 = mul nsw i32 %conv16, %conv14
%add18 = add i32 %add12, %mul17
%arrayidx19 = getelementptr inbounds i16, ptr %in, i32 -4
%8 = load i16, ptr %arrayidx19, align 2
%conv20 = sext i16 %8 to i32
%arrayidx21 = getelementptr inbounds i16, ptr %b, i32 4
%9 = load i16, ptr %arrayidx21, align 2
%conv22 = sext i16 %9 to i32
%mul23 = mul nsw i32 %conv22, %conv20
%add24 = add i32 %add18, %mul23
%arrayidx25 = getelementptr inbounds i16, ptr %in, i32 -5
%10 = load i16, ptr %arrayidx25, align 2
%conv26 = sext i16 %10 to i32
%arrayidx27 = getelementptr inbounds i16, ptr %b, i32 5
%11 = load i16, ptr %arrayidx27, align 2
%conv28 = sext i16 %11 to i32
%mul29 = mul nsw i32 %conv28, %conv26
%add30 = add i32 %add24, %mul29
ret i32 %add30
}
define i32 @with_no_acc_input(ptr nocapture readonly %in, ptr nocapture readonly %b) {
; CHECK-LABEL: @with_no_acc_input(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i16, ptr [[IN:%.*]], i32 -1
; CHECK-NEXT: [[LD_2:%.*]] = load i16, ptr [[ARRAYIDX3]], align 2
; CHECK-NEXT: [[CONV4:%.*]] = sext i16 [[LD_2]] to i32
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i16, ptr [[B:%.*]], i32 1
; CHECK-NEXT: [[LD_3:%.*]] = load i16, ptr [[ARRAYIDX5]], align 2
; CHECK-NEXT: [[CONV6:%.*]] = sext i16 [[LD_3]] to i32
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[CONV6]], [[CONV4]]
; CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -3
; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX13]], align 2
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 2
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX9]], align 2
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP3]], i32 [[MUL]])
; CHECK-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -5
; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX25]], align 2
; CHECK-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 4
; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX21]], align 2
; CHECK-NEXT: [[TMP9:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP6]], i32 [[TMP8]], i32 [[TMP4]])
; CHECK-NEXT: ret i32 [[TMP9]]
;
entry:
%arrayidx3 = getelementptr inbounds i16, ptr %in, i32 -1
%ld.2 = load i16, ptr %arrayidx3, align 2
%conv4 = sext i16 %ld.2 to i32
%arrayidx5 = getelementptr inbounds i16, ptr %b, i32 1
%ld.3 = load i16, ptr %arrayidx5, align 2
%conv6 = sext i16 %ld.3 to i32
%mul = mul nsw i32 %conv6, %conv4
%arrayidx7 = getelementptr inbounds i16, ptr %in, i32 -2
%ld.4 = load i16, ptr %arrayidx7, align 2
%conv8 = sext i16 %ld.4 to i32
%arrayidx9 = getelementptr inbounds i16, ptr %b, i32 2
%ld.5 = load i16, ptr %arrayidx9, align 2
%conv10 = sext i16 %ld.5 to i32
%mul11 = mul nsw i32 %conv10, %conv8
%add12 = add i32 %mul, %mul11
%arrayidx13 = getelementptr inbounds i16, ptr %in, i32 -3
%ld.6 = load i16, ptr %arrayidx13, align 2
%conv14 = sext i16 %ld.6 to i32
%arrayidx15 = getelementptr inbounds i16, ptr %b, i32 3
%ld.7 = load i16, ptr %arrayidx15, align 2
%conv16 = sext i16 %ld.7 to i32
%mul17 = mul nsw i32 %conv16, %conv14
%add18 = add i32 %add12, %mul17
%arrayidx19 = getelementptr inbounds i16, ptr %in, i32 -4
%ld.8 = load i16, ptr %arrayidx19, align 2
%conv20 = sext i16 %ld.8 to i32
%arrayidx21 = getelementptr inbounds i16, ptr %b, i32 4
%ld.9 = load i16, ptr %arrayidx21, align 2
%conv22 = sext i16 %ld.9 to i32
%mul23 = mul nsw i32 %conv22, %conv20
%add24 = add i32 %add18, %mul23
%arrayidx25 = getelementptr inbounds i16, ptr %in, i32 -5
%ld.10 = load i16, ptr %arrayidx25, align 2
%conv26 = sext i16 %ld.10 to i32
%arrayidx27 = getelementptr inbounds i16, ptr %b, i32 5
%ld.11 = load i16, ptr %arrayidx27, align 2
%conv28 = sext i16 %ld.11 to i32
%mul29 = mul nsw i32 %conv28, %conv26
%add30 = add i32 %add24, %mul29
ret i32 %add30
}
define i64 @with_64bit_acc(ptr nocapture readonly %in, ptr nocapture readonly %b) {
; CHECK-LABEL: @with_64bit_acc(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[IN:%.*]], align 2
; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[TMP0]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[B:%.*]], align 2
; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[TMP1]] to i32
; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @bar(i32 [[CONV]], i32 [[CONV2]])
; CHECK-NEXT: [[SEXT_0:%.*]] = sext i32 [[CALL]] to i64
; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -1
; CHECK-NEXT: [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX3]], align 2
; CHECK-NEXT: [[CONV4:%.*]] = sext i16 [[TMP2]] to i32
; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 1
; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[ARRAYIDX5]], align 2
; CHECK-NEXT: [[CONV6:%.*]] = sext i16 [[TMP3]] to i32
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[CONV6]], [[CONV4]]
; CHECK-NEXT: [[SEXT_1:%.*]] = sext i32 [[MUL]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[SEXT_0]], [[SEXT_1]]
; CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -3
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX13]], align 2
; CHECK-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 2
; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX9]], align 2
; CHECK-NEXT: [[TMP8:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP5]], i32 [[TMP7]], i64 [[ADD]])
; CHECK-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i16, ptr [[IN]], i32 -5
; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARRAYIDX25]], align 2
; CHECK-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i16, ptr [[B]], i32 4
; CHECK-NEXT: [[TMP12:%.*]] = load i32, ptr [[ARRAYIDX21]], align 2
; CHECK-NEXT: [[TMP13:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP10]], i32 [[TMP12]], i64 [[TMP8]])
; CHECK-NEXT: ret i64 [[TMP13]]
;
entry:
%0 = load i16, ptr %in, align 2
%conv = sext i16 %0 to i32
%1 = load i16, ptr %b, align 2
%conv2 = sext i16 %1 to i32
%call = tail call i32 @bar(i32 %conv, i32 %conv2)
%sext.0 = sext i32 %call to i64
%arrayidx3 = getelementptr inbounds i16, ptr %in, i32 -1
%2 = load i16, ptr %arrayidx3, align 2
%conv4 = sext i16 %2 to i32
%arrayidx5 = getelementptr inbounds i16, ptr %b, i32 1
%3 = load i16, ptr %arrayidx5, align 2
%conv6 = sext i16 %3 to i32
%mul = mul nsw i32 %conv6, %conv4
%sext.1 = sext i32 %mul to i64
%add = add i64 %sext.0, %sext.1
%arrayidx7 = getelementptr inbounds i16, ptr %in, i32 -2
%4 = load i16, ptr %arrayidx7, align 2
%conv8 = sext i16 %4 to i32
%arrayidx9 = getelementptr inbounds i16, ptr %b, i32 2
%5 = load i16, ptr %arrayidx9, align 2
%conv10 = sext i16 %5 to i32
%mul11 = mul nsw i32 %conv10, %conv8
%sext.2 = sext i32 %mul11 to i64
%add12 = add i64 %add, %sext.2
%arrayidx13 = getelementptr inbounds i16, ptr %in, i32 -3
%6 = load i16, ptr %arrayidx13, align 2
%conv14 = sext i16 %6 to i32
%arrayidx15 = getelementptr inbounds i16, ptr %b, i32 3
%7 = load i16, ptr %arrayidx15, align 2
%conv16 = sext i16 %7 to i32
%mul17 = mul nsw i32 %conv16, %conv14
%sext.3 = sext i32 %mul17 to i64
%add18 = add i64 %add12, %sext.3
%arrayidx19 = getelementptr inbounds i16, ptr %in, i32 -4
%8 = load i16, ptr %arrayidx19, align 2
%conv20 = sext i16 %8 to i32
%arrayidx21 = getelementptr inbounds i16, ptr %b, i32 4
%9 = load i16, ptr %arrayidx21, align 2
%conv22 = sext i16 %9 to i32
%mul23 = mul nsw i32 %conv22, %conv20
%sext.4 = sext i32 %mul23 to i64
%add24 = add i64 %add18, %sext.4
%arrayidx25 = getelementptr inbounds i16, ptr %in, i32 -5
%10 = load i16, ptr %arrayidx25, align 2
%conv26 = sext i16 %10 to i32
%arrayidx27 = getelementptr inbounds i16, ptr %b, i32 5
%11 = load i16, ptr %arrayidx27, align 2
%conv28 = sext i16 %11 to i32
%mul29 = mul nsw i32 %conv28, %conv26
%sext.5 = sext i32 %mul29 to i64
%add30 = add i64 %add24, %sext.5
ret i64 %add30
}
define i64 @with_64bit_add_acc(ptr nocapture readonly %px.10756.unr, ptr nocapture readonly %py.8757.unr, i32 %acc) {
; CHECK-LABEL: @with_64bit_add_acc(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SUM_3758_UNR:%.*]] = sext i32 [[ACC:%.*]] to i64
; CHECK-NEXT: br label [[BB_1:%.*]]
; CHECK: bb.1:
; CHECK-NEXT: [[INCDEC_PTR184_EPIL:%.*]] = getelementptr inbounds i16, ptr [[PX_10756_UNR:%.*]], i32 1
; CHECK-NEXT: [[TMP216:%.*]] = load i16, ptr [[PX_10756_UNR]], align 2
; CHECK-NEXT: [[CONV185_EPIL:%.*]] = sext i16 [[TMP216]] to i32
; CHECK-NEXT: [[INCDEC_PTR186_EPIL:%.*]] = getelementptr inbounds i16, ptr [[PY_8757_UNR:%.*]], i32 -1
; CHECK-NEXT: [[TMP217:%.*]] = load i16, ptr [[PY_8757_UNR]], align 2
; CHECK-NEXT: [[CONV187_EPIL:%.*]] = sext i16 [[TMP217]] to i32
; CHECK-NEXT: [[MUL_EPIL:%.*]] = mul nsw i32 [[CONV187_EPIL]], [[CONV185_EPIL]]
; CHECK-NEXT: [[CONV188_EPIL:%.*]] = sext i32 [[MUL_EPIL]] to i64
; CHECK-NEXT: [[ADD189_EPIL:%.*]] = add nsw i64 [[SUM_3758_UNR]], [[CONV188_EPIL]]
; CHECK-NEXT: [[INCDEC_PTR190_EPIL:%.*]] = getelementptr inbounds i16, ptr [[PX_10756_UNR]], i32 2
; CHECK-NEXT: [[TMP218:%.*]] = load i16, ptr [[INCDEC_PTR184_EPIL]], align 2
; CHECK-NEXT: [[CONV191_EPIL:%.*]] = sext i16 [[TMP218]] to i32
; CHECK-NEXT: [[TMP219:%.*]] = load i16, ptr [[INCDEC_PTR186_EPIL]], align 2
; CHECK-NEXT: [[CONV193_EPIL:%.*]] = sext i16 [[TMP219]] to i32
; CHECK-NEXT: [[MUL194_EPIL:%.*]] = mul nsw i32 [[CONV193_EPIL]], [[CONV191_EPIL]]
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[MUL194_EPIL]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], [[ADD189_EPIL]]
; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[INCDEC_PTR190_EPIL]], align 2
; CHECK-NEXT: [[INCDEC_PTR199_EPIL:%.*]] = getelementptr inbounds i16, ptr [[PY_8757_UNR]], i32 -3
; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[INCDEC_PTR199_EPIL]], align 2
; CHECK-NEXT: [[TMP6:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP5]], i32 [[TMP3]], i64 [[TMP1]])
; CHECK-NEXT: ret i64 [[TMP6]]
;
entry:
%sum.3758.unr = sext i32 %acc to i64
br label %bb.1
bb.1:
%incdec.ptr184.epil = getelementptr inbounds i16, ptr %px.10756.unr, i32 1
%tmp216 = load i16, ptr %px.10756.unr, align 2
%conv185.epil = sext i16 %tmp216 to i32
%incdec.ptr186.epil = getelementptr inbounds i16, ptr %py.8757.unr, i32 -1
%tmp217 = load i16, ptr %py.8757.unr, align 2
%conv187.epil = sext i16 %tmp217 to i32
%mul.epil = mul nsw i32 %conv187.epil, %conv185.epil
%conv188.epil = sext i32 %mul.epil to i64
%add189.epil = add nsw i64 %sum.3758.unr, %conv188.epil
%incdec.ptr190.epil = getelementptr inbounds i16, ptr %px.10756.unr, i32 2
%tmp218 = load i16, ptr %incdec.ptr184.epil, align 2
%conv191.epil = sext i16 %tmp218 to i32
%incdec.ptr192.epil = getelementptr inbounds i16, ptr %py.8757.unr, i32 -2
%tmp219 = load i16, ptr %incdec.ptr186.epil, align 2
%conv193.epil = sext i16 %tmp219 to i32
%mul194.epil = mul nsw i32 %conv193.epil, %conv191.epil
%conv195.epil = sext i32 %mul194.epil to i64
%add196.epil = add nsw i64 %add189.epil, %conv195.epil
%incdec.ptr197.epil = getelementptr inbounds i16, ptr %px.10756.unr, i32 3
%tmp220 = load i16, ptr %incdec.ptr190.epil, align 2
%conv198.epil = sext i16 %tmp220 to i32
%incdec.ptr199.epil = getelementptr inbounds i16, ptr %py.8757.unr, i32 -3
%tmp221 = load i16, ptr %incdec.ptr192.epil, align 2
%conv200.epil = sext i16 %tmp221 to i32
%mul201.epil = mul nsw i32 %conv200.epil, %conv198.epil
%conv202.epil = sext i32 %mul201.epil to i64
%add203.epil = add nsw i64 %add196.epil, %conv202.epil
%tmp222 = load i16, ptr %incdec.ptr197.epil, align 2
%conv205.epil = sext i16 %tmp222 to i32
%tmp223 = load i16, ptr %incdec.ptr199.epil, align 2
%conv207.epil = sext i16 %tmp223 to i32
%mul208.epil = mul nsw i32 %conv207.epil, %conv205.epil
%conv209.epil = sext i32 %mul208.epil to i64
%add210.epil = add nsw i64 %add203.epil, %conv209.epil
ret i64 %add210.epil
}
declare dso_local i32 @bar(i32, i32) local_unnamed_addr