891 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -arm-parallel-dsp -mtriple=armv7-a -S %s -o - | FileCheck %s3 4define i32 @exchange_1(ptr %a, ptr %b, i32 %acc) {5; CHECK-LABEL: @exchange_1(6; CHECK-NEXT: entry:7; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 18; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 19; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 210; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 211; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i1612; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i3213; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 1614; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i1615; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i3216; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i3217; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 218; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 219; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i1620; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])21; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i3222; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 1623; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i1624; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i3225; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 226; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 227; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i3228; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i3229; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i3230; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP14]]31; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP11]]32; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]33; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]34; CHECK-NEXT: ret i32 [[TMP10]]35;36entry:37 %addr.a.1 = getelementptr i16, ptr %a, i32 138 %addr.b.1 = getelementptr i16, ptr %b, i32 139 %ld.a.0 = load i16, ptr %a40 %sext.a.0 = sext i16 %ld.a.0 to i3241 %ld.b.0 = load i16, ptr %b42 %ld.a.1 = load i16, ptr %addr.a.143 %ld.b.1 = load i16, ptr %addr.b.144 %sext.a.1 = sext i16 %ld.a.1 to i3245 %sext.b.1 = sext i16 %ld.b.1 to i3246 %sext.b.0 = sext i16 %ld.b.0 to i3247 %mul.0 = mul i32 %sext.a.0, %sext.b.148 %mul.1 = mul i32 %sext.a.1, %sext.b.049 %add = add i32 %mul.0, %mul.150 %res = add i32 %add, %acc51 ret i32 %res52}53 54define i32 @exchange_2(ptr %a, ptr %b, i32 %acc) {55; CHECK-LABEL: @exchange_2(56; CHECK-NEXT: entry:57; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 158; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 159; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 260; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 261; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i1662; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i3263; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 1664; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i1665; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i3266; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i3267; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 268; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 269; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i1670; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])71; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i3272; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 1673; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i1674; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i3275; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 276; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 277; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i3278; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i3279; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i3280; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP14]], [[TMP3]]81; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP11]], [[TMP6]]82; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]83; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]84; CHECK-NEXT: ret i32 [[TMP10]]85;86entry:87 %addr.a.1 = getelementptr i16, ptr %a, i32 188 %addr.b.1 = getelementptr i16, ptr %b, i32 189 %ld.a.0 = load i16, ptr %a90 %sext.a.0 = sext i16 %ld.a.0 to i3291 %ld.b.0 = load i16, ptr %b92 %ld.a.1 = load i16, ptr %addr.a.193 %ld.b.1 = load i16, ptr %addr.b.194 %sext.a.1 = sext i16 %ld.a.1 to i3295 %sext.b.1 = sext i16 %ld.b.1 to i3296 %sext.b.0 = sext i16 %ld.b.0 to i3297 %mul.0 = mul i32 %sext.b.1, %sext.a.098 %mul.1 = mul i32 %sext.b.0, %sext.a.199 %add = add i32 %mul.0, %mul.1100 %res = add i32 %add, %acc101 ret i32 %res102}103 104define i32 @exchange_3(ptr %a, ptr %b, i32 %acc) {105; CHECK-LABEL: @exchange_3(106; CHECK-NEXT: entry:107; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1108; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1109; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2110; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2111; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16112; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32113; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16114; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16115; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32116; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32117; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2118; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2119; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16120; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP8]], i32 [[TMP1]], i32 [[ACC:%.*]])121; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32122; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16123; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16124; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32125; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2126; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2127; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32128; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32129; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32130; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP14]]131; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP11]]132; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_1]], [[MUL_0]]133; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]134; CHECK-NEXT: ret i32 [[TMP10]]135;136entry:137 %addr.a.1 = getelementptr i16, ptr %a, i32 1138 %addr.b.1 = getelementptr i16, ptr %b, i32 1139 %ld.a.0 = load i16, ptr %a140 %sext.a.0 = sext i16 %ld.a.0 to i32141 %ld.b.0 = load i16, ptr %b142 %ld.a.1 = load i16, ptr %addr.a.1143 %ld.b.1 = load i16, ptr %addr.b.1144 %sext.a.1 = sext i16 %ld.a.1 to i32145 %sext.b.1 = sext i16 %ld.b.1 to i32146 %sext.b.0 = sext i16 %ld.b.0 to i32147 %mul.0 = mul i32 %sext.a.0, %sext.b.1148 %mul.1 = mul i32 %sext.a.1, %sext.b.0149 %add = add i32 %mul.1, %mul.0150 %res = add i32 %add, %acc151 ret i32 %res152}153 154define i32 @exchange_4(ptr %a, ptr %b, i32 %acc) {155; CHECK-LABEL: @exchange_4(156; CHECK-NEXT: entry:157; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1158; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1159; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2160; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2161; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16162; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32163; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16164; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16165; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32166; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32167; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2168; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2169; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16170; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP8]], i32 [[TMP1]], i32 [[ACC:%.*]])171; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32172; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16173; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16174; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32175; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2176; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2177; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32178; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32179; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32180; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP14]], [[TMP3]]181; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP11]], [[TMP6]]182; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_1]], [[MUL_0]]183; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]184; CHECK-NEXT: ret i32 [[TMP10]]185;186entry:187 %addr.a.1 = getelementptr i16, ptr %a, i32 1188 %addr.b.1 = getelementptr i16, ptr %b, i32 1189 %ld.a.0 = load i16, ptr %a190 %sext.a.0 = sext i16 %ld.a.0 to i32191 %ld.b.0 = load i16, ptr %b192 %ld.a.1 = load i16, ptr %addr.a.1193 %ld.b.1 = load i16, ptr %addr.b.1194 %sext.a.1 = sext i16 %ld.a.1 to i32195 %sext.b.1 = sext i16 %ld.b.1 to i32196 %sext.b.0 = sext i16 %ld.b.0 to i32197 %mul.0 = mul i32 %sext.b.1, %sext.a.0198 %mul.1 = mul i32 %sext.b.0, %sext.a.1199 %add = add i32 %mul.1, %mul.0200 %res = add i32 %add, %acc201 ret i32 %res202}203 204define i32 @exchange_multi_use_1(ptr %a, ptr %b, i32 %acc) {205; CHECK-LABEL: @exchange_multi_use_1(206; CHECK-NEXT: entry:207; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1208; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1209; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2210; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2211; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16212; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32213; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16214; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16215; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32216; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32217; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2218; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2219; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16220; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])221; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32222; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16223; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16224; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32225; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2226; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2227; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32228; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32229; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32230; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP14]]231; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP11]]232; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]233; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2234; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3235; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2236; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ADDR_A_2]], align 2237; CHECK-NEXT: [[TMP17:%.*]] = trunc i32 [[TMP16]] to i16238; CHECK-NEXT: [[TMP18:%.*]] = call i32 @llvm.arm.smlad(i32 [[TMP16]], i32 [[TMP8]], i32 [[TMP10]])239; CHECK-NEXT: [[TMP19:%.*]] = sext i16 [[TMP17]] to i32240; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP16]], 16241; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i16242; CHECK-NEXT: [[TMP22:%.*]] = sext i16 [[TMP21]] to i32243; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2244; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32245; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32246; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP22]], [[TMP14]]247; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP19]], [[TMP11]]248; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]249; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[ADD]], [[ADD_1]]250; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD_2]], [[ACC]]251; CHECK-NEXT: ret i32 [[TMP18]]252;253entry:254 %addr.a.1 = getelementptr i16, ptr %a, i32 1255 %addr.b.1 = getelementptr i16, ptr %b, i32 1256 %ld.a.0 = load i16, ptr %a257 %sext.a.0 = sext i16 %ld.a.0 to i32258 %ld.b.0 = load i16, ptr %b259 %ld.a.1 = load i16, ptr %addr.a.1260 %ld.b.1 = load i16, ptr %addr.b.1261 %sext.a.1 = sext i16 %ld.a.1 to i32262 %sext.b.1 = sext i16 %ld.b.1 to i32263 %sext.b.0 = sext i16 %ld.b.0 to i32264 %mul.0 = mul i32 %sext.a.0, %sext.b.1265 %mul.1 = mul i32 %sext.a.1, %sext.b.0266 %add = add i32 %mul.0, %mul.1267 %addr.a.2 = getelementptr i16, ptr %a, i32 2268 %addr.a.3 = getelementptr i16, ptr %a, i32 3269 %ld.a.2 = load i16, ptr %addr.a.2270 %ld.a.3 = load i16, ptr %addr.a.3271 %sext.a.2 = sext i16 %ld.a.2 to i32272 %sext.a.3 = sext i16 %ld.a.3 to i32273 %mul.2 = mul i32 %sext.a.3, %sext.b.1274 %mul.3 = mul i32 %sext.a.2, %sext.b.0275 %add.1 = add i32 %mul.2, %mul.3276 %add.2 = add i32 %add, %add.1277 %res = add i32 %add.2, %acc278 ret i32 %res279}280 281define i64 @exchange_multi_use_64_1(ptr %a, ptr %b, i64 %acc) {282; CHECK-LABEL: @exchange_multi_use_64_1(283; CHECK-NEXT: entry:284; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1285; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1286; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2287; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2288; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16289; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32290; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16291; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16292; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32293; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32294; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2295; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2296; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16297; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP1]], i32 [[TMP8]], i64 [[ACC:%.*]])298; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32299; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16300; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16301; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32302; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2303; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2304; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32305; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32306; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32307; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP14]]308; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP11]]309; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]310; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2311; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3312; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2313; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ADDR_A_2]], align 2314; CHECK-NEXT: [[TMP17:%.*]] = trunc i32 [[TMP16]] to i16315; CHECK-NEXT: [[TMP18:%.*]] = call i64 @llvm.arm.smlald(i32 [[TMP16]], i32 [[TMP8]], i64 [[TMP10]])316; CHECK-NEXT: [[TMP19:%.*]] = sext i16 [[TMP17]] to i32317; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP16]], 16318; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i16319; CHECK-NEXT: [[TMP22:%.*]] = sext i16 [[TMP21]] to i32320; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2321; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32322; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32323; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP22]], [[TMP14]]324; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP19]], [[TMP11]]325; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]326; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[ADD]], [[ADD_1]]327; CHECK-NEXT: [[SEXT_ADD_2:%.*]] = sext i32 [[ADD_2]] to i64328; CHECK-NEXT: [[RES:%.*]] = add i64 [[SEXT_ADD_2]], [[ACC]]329; CHECK-NEXT: ret i64 [[TMP18]]330;331entry:332 %addr.a.1 = getelementptr i16, ptr %a, i32 1333 %addr.b.1 = getelementptr i16, ptr %b, i32 1334 %ld.a.0 = load i16, ptr %a335 %sext.a.0 = sext i16 %ld.a.0 to i32336 %ld.b.0 = load i16, ptr %b337 %ld.a.1 = load i16, ptr %addr.a.1338 %ld.b.1 = load i16, ptr %addr.b.1339 %sext.a.1 = sext i16 %ld.a.1 to i32340 %sext.b.1 = sext i16 %ld.b.1 to i32341 %sext.b.0 = sext i16 %ld.b.0 to i32342 %mul.0 = mul i32 %sext.a.0, %sext.b.1343 %mul.1 = mul i32 %sext.a.1, %sext.b.0344 %add = add i32 %mul.0, %mul.1345 %addr.a.2 = getelementptr i16, ptr %a, i32 2346 %addr.a.3 = getelementptr i16, ptr %a, i32 3347 %ld.a.2 = load i16, ptr %addr.a.2348 %ld.a.3 = load i16, ptr %addr.a.3349 %sext.a.2 = sext i16 %ld.a.2 to i32350 %sext.a.3 = sext i16 %ld.a.3 to i32351 %mul.2 = mul i32 %sext.a.3, %sext.b.1352 %mul.3 = mul i32 %sext.a.2, %sext.b.0353 %add.1 = add i32 %mul.2, %mul.3354 %add.2 = add i32 %add, %add.1355 %sext.add.2 = sext i32 %add.2 to i64356 %res = add i64 %sext.add.2, %acc357 ret i64 %res358}359 360define i64 @exchange_multi_use_64_2(ptr %a, ptr %b, i64 %acc) {361; CHECK-LABEL: @exchange_multi_use_64_2(362; CHECK-NEXT: entry:363; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1364; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1365; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2366; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2367; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16368; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32369; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16370; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16371; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32372; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32373; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2374; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2375; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16376; CHECK-NEXT: [[TMP10:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP1]], i32 [[TMP8]], i64 [[ACC:%.*]])377; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32378; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16379; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16380; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32381; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2382; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2383; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32384; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32385; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32386; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP14]]387; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP11]]388; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]389; CHECK-NEXT: [[SEXT_ADD:%.*]] = sext i32 [[ADD]] to i64390; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2391; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3392; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2393; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ADDR_A_2]], align 2394; CHECK-NEXT: [[TMP17:%.*]] = trunc i32 [[TMP16]] to i16395; CHECK-NEXT: [[TMP18:%.*]] = call i64 @llvm.arm.smlald(i32 [[TMP16]], i32 [[TMP8]], i64 [[TMP10]])396; CHECK-NEXT: [[TMP19:%.*]] = sext i16 [[TMP17]] to i32397; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP16]], 16398; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i16399; CHECK-NEXT: [[TMP22:%.*]] = sext i16 [[TMP21]] to i32400; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2401; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32402; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32403; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP22]], [[TMP14]]404; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP19]], [[TMP11]]405; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]406; CHECK-NEXT: [[SEXT_ADD_1:%.*]] = sext i32 [[ADD_1]] to i64407; CHECK-NEXT: [[ADD_2:%.*]] = add i64 [[SEXT_ADD]], [[SEXT_ADD_1]]408; CHECK-NEXT: [[RES:%.*]] = add i64 [[ADD_2]], [[ACC]]409; CHECK-NEXT: ret i64 [[TMP18]]410;411entry:412 %addr.a.1 = getelementptr i16, ptr %a, i32 1413 %addr.b.1 = getelementptr i16, ptr %b, i32 1414 %ld.a.0 = load i16, ptr %a415 %sext.a.0 = sext i16 %ld.a.0 to i32416 %ld.b.0 = load i16, ptr %b417 %ld.a.1 = load i16, ptr %addr.a.1418 %ld.b.1 = load i16, ptr %addr.b.1419 %sext.a.1 = sext i16 %ld.a.1 to i32420 %sext.b.1 = sext i16 %ld.b.1 to i32421 %sext.b.0 = sext i16 %ld.b.0 to i32422 %mul.0 = mul i32 %sext.a.0, %sext.b.1423 %mul.1 = mul i32 %sext.a.1, %sext.b.0424 %add = add i32 %mul.0, %mul.1425 %sext.add = sext i32 %add to i64426 %addr.a.2 = getelementptr i16, ptr %a, i32 2427 %addr.a.3 = getelementptr i16, ptr %a, i32 3428 %ld.a.2 = load i16, ptr %addr.a.2429 %ld.a.3 = load i16, ptr %addr.a.3430 %sext.a.2 = sext i16 %ld.a.2 to i32431 %sext.a.3 = sext i16 %ld.a.3 to i32432 %mul.2 = mul i32 %sext.a.3, %sext.b.1433 %mul.3 = mul i32 %sext.a.2, %sext.b.0434 %add.1 = add i32 %mul.2, %mul.3435 %sext.add.1 = sext i32 %add.1 to i64436 %add.2 = add i64 %sext.add, %sext.add.1437 %res = add i64 %add.2, %acc438 ret i64 %res439}440 441define i32 @exchange_multi_use_2(ptr %a, ptr %b, i32 %acc) {442; CHECK-LABEL: @exchange_multi_use_2(443; CHECK-NEXT: entry:444; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1445; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1446; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2447; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2448; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16449; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32450; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16451; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16452; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32453; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32454; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2455; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2456; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16457; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smlad(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])458; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32459; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16460; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16461; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32462; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2463; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2464; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32465; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32466; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32467; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP11]]468; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP14]]469; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]470; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2471; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3472; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2473; CHECK-NEXT: [[TMP16:%.*]] = load i32, ptr [[ADDR_A_2]], align 2474; CHECK-NEXT: [[TMP17:%.*]] = trunc i32 [[TMP16]] to i16475; CHECK-NEXT: [[TMP18:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP8]], i32 [[TMP16]], i32 [[TMP10]])476; CHECK-NEXT: [[TMP19:%.*]] = sext i16 [[TMP17]] to i32477; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP16]], 16478; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i16479; CHECK-NEXT: [[TMP22:%.*]] = sext i16 [[TMP21]] to i32480; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2481; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32482; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32483; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP11]], [[TMP22]]484; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP14]], [[TMP19]]485; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]486; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[ADD]], [[ADD_1]]487; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD_2]], [[ACC]]488; CHECK-NEXT: ret i32 [[TMP18]]489;490entry:491 %addr.a.1 = getelementptr i16, ptr %a, i32 1492 %addr.b.1 = getelementptr i16, ptr %b, i32 1493 %ld.a.0 = load i16, ptr %a494 %sext.a.0 = sext i16 %ld.a.0 to i32495 %ld.b.0 = load i16, ptr %b496 %ld.a.1 = load i16, ptr %addr.a.1497 %ld.b.1 = load i16, ptr %addr.b.1498 %sext.a.1 = sext i16 %ld.a.1 to i32499 %sext.b.1 = sext i16 %ld.b.1 to i32500 %sext.b.0 = sext i16 %ld.b.0 to i32501 %mul.0 = mul i32 %sext.a.0, %sext.b.0502 %mul.1 = mul i32 %sext.a.1, %sext.b.1503 %add = add i32 %mul.0, %mul.1504 %addr.a.2 = getelementptr i16, ptr %a, i32 2505 %addr.a.3 = getelementptr i16, ptr %a, i32 3506 %ld.a.2 = load i16, ptr %addr.a.2507 %ld.a.3 = load i16, ptr %addr.a.3508 %sext.a.2 = sext i16 %ld.a.2 to i32509 %sext.a.3 = sext i16 %ld.a.3 to i32510 %mul.2 = mul i32 %sext.b.0, %sext.a.3511 %mul.3 = mul i32 %sext.b.1, %sext.a.2512 %add.1 = add i32 %mul.2, %mul.3513 %add.2 = add i32 %add, %add.1514 %res = add i32 %add.2, %acc515 ret i32 %res516}517 518; TODO: Why aren't two intrinsics generated?519define i32 @exchange_multi_use_3(ptr %a, ptr %b, i32 %acc) {520; CHECK-LABEL: @exchange_multi_use_3(521; CHECK-NEXT: entry:522; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1523; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1524; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2525; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32526; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2527; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 2528; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16529; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32530; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16531; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16532; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32533; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2534; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2535; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32536; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32537; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32538; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2539; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3540; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2541; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ADDR_A_2]], align 2542; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16543; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 0)544; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32545; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16546; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16547; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32548; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2549; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32550; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32551; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP3]], [[TMP14]]552; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP6]], [[TMP11]]553; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[SEXT_A_0]], [[TMP3]]554; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[SEXT_A_1]], [[TMP6]]555; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]556; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]557; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[ADD]], [[TMP10]]558; CHECK-NEXT: [[RES:%.*]] = add i32 [[ACC:%.*]], [[SUB]]559; CHECK-NEXT: ret i32 [[RES]]560;561entry:562 %addr.a.1 = getelementptr i16, ptr %a, i32 1563 %addr.b.1 = getelementptr i16, ptr %b, i32 1564 %ld.a.0 = load i16, ptr %a565 %sext.a.0 = sext i16 %ld.a.0 to i32566 %ld.b.0 = load i16, ptr %b567 %ld.a.1 = load i16, ptr %addr.a.1568 %ld.b.1 = load i16, ptr %addr.b.1569 %sext.a.1 = sext i16 %ld.a.1 to i32570 %sext.b.1 = sext i16 %ld.b.1 to i32571 %sext.b.0 = sext i16 %ld.b.0 to i32572 %addr.a.2 = getelementptr i16, ptr %a, i32 2573 %addr.a.3 = getelementptr i16, ptr %a, i32 3574 %ld.a.2 = load i16, ptr %addr.a.2575 %ld.a.3 = load i16, ptr %addr.a.3576 %sext.a.2 = sext i16 %ld.a.2 to i32577 %sext.a.3 = sext i16 %ld.a.3 to i32578 %mul.2 = mul i32 %sext.b.0, %sext.a.3579 %mul.3 = mul i32 %sext.b.1, %sext.a.2580 %mul.0 = mul i32 %sext.a.0, %sext.b.0581 %mul.1 = mul i32 %sext.a.1, %sext.b.1582 %add = add i32 %mul.0, %mul.1583 %add.1 = add i32 %mul.2, %mul.3584 %sub = sub i32 %add, %add.1585 %res = add i32 %acc, %sub586 ret i32 %res587}588 589; TODO: Would it be better to generate a smlad and then sign extend it?590define i64 @exchange_multi_use_64_3(ptr %a, ptr %b, i64 %acc) {591; CHECK-LABEL: @exchange_multi_use_64_3(592; CHECK-NEXT: entry:593; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1594; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1595; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2596; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2597; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16598; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32599; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16600; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16601; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32602; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32603; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2604; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2605; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16606; CHECK-NEXT: [[TMP10:%.*]] = sext i16 [[TMP9]] to i32607; CHECK-NEXT: [[TMP11:%.*]] = lshr i32 [[TMP8]], 16608; CHECK-NEXT: [[TMP12:%.*]] = trunc i32 [[TMP11]] to i16609; CHECK-NEXT: [[TMP13:%.*]] = sext i16 [[TMP12]] to i32610; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2611; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2612; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32613; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32614; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32615; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2616; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3617; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2618; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[ADDR_A_2]], align 2619; CHECK-NEXT: [[TMP16:%.*]] = trunc i32 [[TMP15]] to i16620; CHECK-NEXT: [[TMP17:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[TMP8]], i32 [[TMP15]], i64 0)621; CHECK-NEXT: [[TMP18:%.*]] = call i64 @llvm.arm.smlald(i32 [[TMP1]], i32 [[TMP8]], i64 [[TMP17]])622; CHECK-NEXT: [[TMP19:%.*]] = sext i16 [[TMP16]] to i32623; CHECK-NEXT: [[TMP20:%.*]] = lshr i32 [[TMP15]], 16624; CHECK-NEXT: [[TMP21:%.*]] = trunc i32 [[TMP20]] to i16625; CHECK-NEXT: [[TMP22:%.*]] = sext i16 [[TMP21]] to i32626; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2627; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32628; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32629; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP10]], [[TMP22]]630; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP13]], [[TMP19]]631; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP10]]632; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP13]]633; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]634; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]635; CHECK-NEXT: [[SEXT_ADD:%.*]] = sext i32 [[ADD]] to i64636; CHECK-NEXT: [[SEXT_ADD_1:%.*]] = sext i32 [[ADD_1]] to i64637; CHECK-NEXT: [[ADD_2:%.*]] = add i64 [[SEXT_ADD]], [[SEXT_ADD_1]]638; CHECK-NEXT: [[RES:%.*]] = sub i64 [[ACC:%.*]], [[TMP18]]639; CHECK-NEXT: ret i64 [[RES]]640;641entry:642 %addr.a.1 = getelementptr i16, ptr %a, i32 1643 %addr.b.1 = getelementptr i16, ptr %b, i32 1644 %ld.a.0 = load i16, ptr %a645 %sext.a.0 = sext i16 %ld.a.0 to i32646 %ld.b.0 = load i16, ptr %b647 %ld.a.1 = load i16, ptr %addr.a.1648 %ld.b.1 = load i16, ptr %addr.b.1649 %sext.a.1 = sext i16 %ld.a.1 to i32650 %sext.b.1 = sext i16 %ld.b.1 to i32651 %sext.b.0 = sext i16 %ld.b.0 to i32652 %addr.a.2 = getelementptr i16, ptr %a, i32 2653 %addr.a.3 = getelementptr i16, ptr %a, i32 3654 %ld.a.2 = load i16, ptr %addr.a.2655 %ld.a.3 = load i16, ptr %addr.a.3656 %sext.a.2 = sext i16 %ld.a.2 to i32657 %sext.a.3 = sext i16 %ld.a.3 to i32658 %mul.2 = mul i32 %sext.b.0, %sext.a.3659 %mul.3 = mul i32 %sext.b.1, %sext.a.2660 %mul.0 = mul i32 %sext.a.0, %sext.b.0661 %mul.1 = mul i32 %sext.a.1, %sext.b.1662 %add = add i32 %mul.0, %mul.1663 %add.1 = add i32 %mul.2, %mul.3664 %sext.add = sext i32 %add to i64665 %sext.add.1 = sext i32 %add.1 to i64666 %add.2 = add i64 %sext.add, %sext.add.1667 %res = sub i64 %acc, %add.2668 ret i64 %res669}670 671; TODO: Why isn't smladx generated too?672define i32 @exchange_multi_use_4(ptr %a, ptr %b, i32 %acc) {673; CHECK-LABEL: @exchange_multi_use_4(674; CHECK-NEXT: entry:675; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1676; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1677; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2678; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2679; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16680; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32681; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16682; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16683; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32684; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32685; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2686; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2687; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16688; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smlad(i32 [[TMP1]], i32 [[TMP8]], i32 0)689; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32690; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16691; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16692; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32693; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2694; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2695; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32696; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32697; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32698; CHECK-NEXT: [[ADDR_A_2:%.*]] = getelementptr i16, ptr [[A]], i32 2699; CHECK-NEXT: [[ADDR_A_3:%.*]] = getelementptr i16, ptr [[A]], i32 3700; CHECK-NEXT: [[LD_A_2:%.*]] = load i16, ptr [[ADDR_A_2]], align 2701; CHECK-NEXT: [[LD_A_3:%.*]] = load i16, ptr [[ADDR_A_3]], align 2702; CHECK-NEXT: [[SEXT_A_2:%.*]] = sext i16 [[LD_A_2]] to i32703; CHECK-NEXT: [[SEXT_A_3:%.*]] = sext i16 [[LD_A_3]] to i32704; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[TMP11]], [[SEXT_A_3]]705; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[TMP14]], [[SEXT_A_2]]706; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP3]], [[TMP11]]707; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP6]], [[TMP14]]708; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[MUL_2]], [[MUL_3]]709; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]710; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[TMP10]], [[ADD_1]]711; CHECK-NEXT: [[RES:%.*]] = add i32 [[ACC:%.*]], [[SUB]]712; CHECK-NEXT: ret i32 [[RES]]713;714entry:715 %addr.a.1 = getelementptr i16, ptr %a, i32 1716 %addr.b.1 = getelementptr i16, ptr %b, i32 1717 %ld.a.0 = load i16, ptr %a718 %sext.a.0 = sext i16 %ld.a.0 to i32719 %ld.b.0 = load i16, ptr %b720 %ld.a.1 = load i16, ptr %addr.a.1721 %ld.b.1 = load i16, ptr %addr.b.1722 %sext.a.1 = sext i16 %ld.a.1 to i32723 %sext.b.1 = sext i16 %ld.b.1 to i32724 %sext.b.0 = sext i16 %ld.b.0 to i32725 %addr.a.2 = getelementptr i16, ptr %a, i32 2726 %addr.a.3 = getelementptr i16, ptr %a, i32 3727 %ld.a.2 = load i16, ptr %addr.a.2728 %ld.a.3 = load i16, ptr %addr.a.3729 %sext.a.2 = sext i16 %ld.a.2 to i32730 %sext.a.3 = sext i16 %ld.a.3 to i32731 %mul.2 = mul i32 %sext.b.0, %sext.a.3732 %mul.3 = mul i32 %sext.b.1, %sext.a.2733 %mul.0 = mul i32 %sext.a.0, %sext.b.0734 %mul.1 = mul i32 %sext.a.1, %sext.b.1735 %add.1 = add i32 %mul.2, %mul.3736 %add = add i32 %mul.0, %mul.1737 %sub = sub i32 %add, %add.1738 %res = add i32 %acc, %sub739 ret i32 %res740}741 742define i32 @exchange_swap(ptr %a, ptr %b, i32 %acc) {743; CHECK-LABEL: @exchange_swap(744; CHECK-NEXT: entry:745; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1746; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1747; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2748; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2749; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16750; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32751; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16752; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16753; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32754; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32755; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2756; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2757; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16758; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP8]], i32 [[TMP1]], i32 [[ACC:%.*]])759; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32760; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16761; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16762; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32763; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2764; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2765; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32766; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32767; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32768; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP6]], [[TMP11]]769; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP3]], [[TMP14]]770; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_0]], [[MUL_1]]771; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]772; CHECK-NEXT: ret i32 [[TMP10]]773;774entry:775 %addr.a.1 = getelementptr i16, ptr %a, i32 1776 %addr.b.1 = getelementptr i16, ptr %b, i32 1777 %ld.a.0 = load i16, ptr %a778 %sext.a.0 = sext i16 %ld.a.0 to i32779 %ld.b.0 = load i16, ptr %b780 %ld.a.1 = load i16, ptr %addr.a.1781 %ld.b.1 = load i16, ptr %addr.b.1782 %sext.a.1 = sext i16 %ld.a.1 to i32783 %sext.b.1 = sext i16 %ld.b.1 to i32784 %sext.b.0 = sext i16 %ld.b.0 to i32785 %mul.0 = mul i32 %sext.a.1, %sext.b.0786 %mul.1 = mul i32 %sext.a.0, %sext.b.1787 %add = add i32 %mul.0, %mul.1788 %res = add i32 %add, %acc789 ret i32 %res790}791 792define i32 @exchange_swap_2(ptr %a, ptr %b, i32 %acc) {793; CHECK-LABEL: @exchange_swap_2(794; CHECK-NEXT: entry:795; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1796; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1797; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2798; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2799; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16800; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32801; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16802; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16803; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32804; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32805; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2806; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2807; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16808; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])809; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32810; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16811; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16812; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32813; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2814; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2815; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32816; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32817; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32818; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP6]], [[TMP11]]819; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP3]], [[TMP14]]820; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_1]], [[MUL_0]]821; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]822; CHECK-NEXT: ret i32 [[TMP10]]823;824entry:825 %addr.a.1 = getelementptr i16, ptr %a, i32 1826 %addr.b.1 = getelementptr i16, ptr %b, i32 1827 %ld.a.0 = load i16, ptr %a828 %sext.a.0 = sext i16 %ld.a.0 to i32829 %ld.b.0 = load i16, ptr %b830 %ld.a.1 = load i16, ptr %addr.a.1831 %ld.b.1 = load i16, ptr %addr.b.1832 %sext.a.1 = sext i16 %ld.a.1 to i32833 %sext.b.1 = sext i16 %ld.b.1 to i32834 %sext.b.0 = sext i16 %ld.b.0 to i32835 %mul.0 = mul i32 %sext.a.1, %sext.b.0836 %mul.1 = mul i32 %sext.a.0, %sext.b.1837 %add = add i32 %mul.1, %mul.0838 %res = add i32 %add, %acc839 ret i32 %res840}841 842define i32 @exchange_swap_3(ptr %a, ptr %b, i32 %acc) {843; CHECK-LABEL: @exchange_swap_3(844; CHECK-NEXT: entry:845; CHECK-NEXT: [[ADDR_A_1:%.*]] = getelementptr i16, ptr [[A:%.*]], i32 1846; CHECK-NEXT: [[ADDR_B_1:%.*]] = getelementptr i16, ptr [[B:%.*]], i32 1847; CHECK-NEXT: [[LD_A_0:%.*]] = load i16, ptr [[A]], align 2848; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[A]], align 2849; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16850; CHECK-NEXT: [[TMP3:%.*]] = sext i16 [[TMP2]] to i32851; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP1]], 16852; CHECK-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i16853; CHECK-NEXT: [[TMP6:%.*]] = sext i16 [[TMP5]] to i32854; CHECK-NEXT: [[SEXT_A_0:%.*]] = sext i16 [[LD_A_0]] to i32855; CHECK-NEXT: [[LD_B_0:%.*]] = load i16, ptr [[B]], align 2856; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[B]], align 2857; CHECK-NEXT: [[TMP9:%.*]] = trunc i32 [[TMP8]] to i16858; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.arm.smladx(i32 [[TMP1]], i32 [[TMP8]], i32 [[ACC:%.*]])859; CHECK-NEXT: [[TMP11:%.*]] = sext i16 [[TMP9]] to i32860; CHECK-NEXT: [[TMP12:%.*]] = lshr i32 [[TMP8]], 16861; CHECK-NEXT: [[TMP13:%.*]] = trunc i32 [[TMP12]] to i16862; CHECK-NEXT: [[TMP14:%.*]] = sext i16 [[TMP13]] to i32863; CHECK-NEXT: [[LD_A_1:%.*]] = load i16, ptr [[ADDR_A_1]], align 2864; CHECK-NEXT: [[LD_B_1:%.*]] = load i16, ptr [[ADDR_B_1]], align 2865; CHECK-NEXT: [[SEXT_A_1:%.*]] = sext i16 [[LD_A_1]] to i32866; CHECK-NEXT: [[SEXT_B_1:%.*]] = sext i16 [[LD_B_1]] to i32867; CHECK-NEXT: [[SEXT_B_0:%.*]] = sext i16 [[LD_B_0]] to i32868; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[TMP11]], [[TMP6]]869; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[TMP14]], [[TMP3]]870; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL_1]], [[MUL_0]]871; CHECK-NEXT: [[RES:%.*]] = add i32 [[ADD]], [[ACC]]872; CHECK-NEXT: ret i32 [[TMP10]]873;874entry:875 %addr.a.1 = getelementptr i16, ptr %a, i32 1876 %addr.b.1 = getelementptr i16, ptr %b, i32 1877 %ld.a.0 = load i16, ptr %a878 %sext.a.0 = sext i16 %ld.a.0 to i32879 %ld.b.0 = load i16, ptr %b880 %ld.a.1 = load i16, ptr %addr.a.1881 %ld.b.1 = load i16, ptr %addr.b.1882 %sext.a.1 = sext i16 %ld.a.1 to i32883 %sext.b.1 = sext i16 %ld.b.1 to i32884 %sext.b.0 = sext i16 %ld.b.0 to i32885 %mul.0 = mul i32 %sext.b.0, %sext.a.1886 %mul.1 = mul i32 %sext.b.1, %sext.a.0887 %add = add i32 %mul.1, %mul.0888 %res = add i32 %add, %acc889 ret i32 %res890}891