1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=thumbv7m -mattr=+dsp %s -o - | FileCheck %s --check-prefix=DSP 3; RUN: llc -mtriple=armv7a %s -o - | FileCheck %s --check-prefix=ARM7 4; RUN: llc -mtriple=thumbv7m -mattr=-dsp %s -o - | FileCheck %s --check-prefix=NODSP 5 6define hidden i32 @SMMULR_SMMLAR(i32 %a, i32 %b0, i32 %b1, i32 %Xn, i32 %Xn1) local_unnamed_addr { 7; DSP-LABEL: SMMULR_SMMLAR: 8; DSP: @ %bb.0: @ %entry 9; DSP-NEXT: ldr r0, [sp] 10; DSP-NEXT: smmulr r0, r0, r2 11; DSP-NEXT: smmlar r0, r3, r1, r0 12; DSP-NEXT: bx lr 13; 14; ARM7-LABEL: SMMULR_SMMLAR: 15; ARM7: @ %bb.0: @ %entry 16; ARM7-NEXT: ldr r0, [sp] 17; ARM7-NEXT: smmulr r0, r0, r2 18; ARM7-NEXT: smmlar r0, r3, r1, r0 19; ARM7-NEXT: bx lr 20; 21; NODSP-LABEL: SMMULR_SMMLAR: 22; NODSP: @ %bb.0: @ %entry 23; NODSP-NEXT: push {r4, lr} 24; NODSP-NEXT: ldr.w lr, [sp, #8] 25; NODSP-NEXT: movs r0, #0 26; NODSP-NEXT: mov.w r4, #-2147483648 27; NODSP-NEXT: mov.w r12, #-2147483648 28; NODSP-NEXT: smlal r4, r0, lr, r2 29; NODSP-NEXT: smlal r12, r0, r3, r1 30; NODSP-NEXT: pop {r4, pc} 31entry: 32 %conv = sext i32 %b1 to i64 33 %conv1 = sext i32 %Xn1 to i64 34 %mul = mul nsw i64 %conv1, %conv 35 %add = add nsw i64 %mul, 2147483648 36 %0 = and i64 %add, -4294967296 37 %conv4 = sext i32 %b0 to i64 38 %conv5 = sext i32 %Xn to i64 39 %mul6 = mul nsw i64 %conv5, %conv4 40 %add7 = add i64 %mul6, 2147483648 41 %add8 = add i64 %add7, %0 42 %1 = lshr i64 %add8, 32 43 %conv10 = trunc i64 %1 to i32 44 ret i32 %conv10 45} 46 47define hidden i32 @SMMULR(i32 %a, i32 %b) local_unnamed_addr { 48; DSP-LABEL: SMMULR: 49; DSP: @ %bb.0: @ %entry 50; DSP-NEXT: smmulr r0, r1, r0 51; DSP-NEXT: bx lr 52; 53; ARM7-LABEL: SMMULR: 54; ARM7: @ %bb.0: @ %entry 55; ARM7-NEXT: smmulr r0, r1, r0 56; ARM7-NEXT: bx lr 57; 58; NODSP-LABEL: SMMULR: 59; NODSP: @ %bb.0: @ %entry 60; NODSP-NEXT: movs r2, #0 61; NODSP-NEXT: mov.w r3, #-2147483648 62; NODSP-NEXT: smlal r3, r2, r1, r0 63; NODSP-NEXT: mov r0, r2 64; NODSP-NEXT: bx lr 65entry: 66 %conv = sext i32 %a to i64 67 %conv1 = sext i32 %b to i64 68 %mul = mul nsw i64 %conv1, %conv 69 %add = add nsw i64 %mul, 2147483648 70 %0 = lshr i64 %add, 32 71 %conv2 = trunc i64 %0 to i32 72 ret i32 %conv2 73} 74 75define hidden i32 @SMMUL(i32 %a, i32 %b) local_unnamed_addr { 76; DSP-LABEL: SMMUL: 77; DSP: @ %bb.0: @ %entry 78; DSP-NEXT: smmul r0, r1, r0 79; DSP-NEXT: bx lr 80; 81; ARM7-LABEL: SMMUL: 82; ARM7: @ %bb.0: @ %entry 83; ARM7-NEXT: smmul r0, r1, r0 84; ARM7-NEXT: bx lr 85; 86; NODSP-LABEL: SMMUL: 87; NODSP: @ %bb.0: @ %entry 88; NODSP-NEXT: smull r1, r0, r1, r0 89; NODSP-NEXT: bx lr 90entry: 91 %conv = sext i32 %a to i64 92 %conv1 = sext i32 %b to i64 93 %mul = mul nsw i64 %conv1, %conv 94 %0 = lshr i64 %mul, 32 95 %conv2 = trunc i64 %0 to i32 96 ret i32 %conv2 97} 98 99define hidden i32 @SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 100; DSP-LABEL: SMMLSR: 101; DSP: @ %bb.0: @ %entry 102; DSP-NEXT: smmlsr r0, r2, r1, r0 103; DSP-NEXT: bx lr 104; 105; ARM7-LABEL: SMMLSR: 106; ARM7: @ %bb.0: @ %entry 107; ARM7-NEXT: smmlsr r0, r2, r1, r0 108; ARM7-NEXT: bx lr 109; 110; NODSP-LABEL: SMMLSR: 111; NODSP: @ %bb.0: @ %entry 112; NODSP-NEXT: smull r1, r2, r2, r1 113; NODSP-NEXT: rsbs.w r1, r1, #-2147483648 114; NODSP-NEXT: sbcs r0, r2 115; NODSP-NEXT: bx lr 116entry: 117 %conv6 = zext i32 %a to i64 118 %shl = shl nuw i64 %conv6, 32 119 %conv1 = sext i32 %b to i64 120 %conv2 = sext i32 %c to i64 121 %mul = mul nsw i64 %conv2, %conv1 122 %sub = or i64 %shl, 2147483648 123 %add = sub i64 %sub, %mul 124 %0 = lshr i64 %add, 32 125 %conv3 = trunc i64 %0 to i32 126 ret i32 %conv3 127} 128 129define hidden i32 @NOT_SMMLSR(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 130; DSP-LABEL: NOT_SMMLSR: 131; DSP: @ %bb.0: @ %entry 132; DSP-NEXT: smmulr r1, r2, r1 133; DSP-NEXT: subs r0, r0, r1 134; DSP-NEXT: bx lr 135; 136; ARM7-LABEL: NOT_SMMLSR: 137; ARM7: @ %bb.0: @ %entry 138; ARM7-NEXT: smmulr r1, r2, r1 139; ARM7-NEXT: sub r0, r0, r1 140; ARM7-NEXT: bx lr 141; 142; NODSP-LABEL: NOT_SMMLSR: 143; NODSP: @ %bb.0: @ %entry 144; NODSP-NEXT: mov.w r12, #0 145; NODSP-NEXT: mov.w r3, #-2147483648 146; NODSP-NEXT: smlal r3, r12, r2, r1 147; NODSP-NEXT: sub.w r0, r0, r12 148; NODSP-NEXT: bx lr 149entry: 150 %conv = sext i32 %b to i64 151 %conv1 = sext i32 %c to i64 152 %mul = mul nsw i64 %conv1, %conv 153 %add = add nsw i64 %mul, 2147483648 154 %0 = lshr i64 %add, 32 155 %conv2 = trunc i64 %0 to i32 156 %sub = sub nsw i32 %a, %conv2 157 ret i32 %sub 158} 159 160define hidden i32 @SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 161; DSP-LABEL: SMMLS: 162; DSP: @ %bb.0: @ %entry 163; DSP-NEXT: smmls r0, r2, r1, r0 164; DSP-NEXT: bx lr 165; 166; ARM7-LABEL: SMMLS: 167; ARM7: @ %bb.0: @ %entry 168; ARM7-NEXT: smmls r0, r2, r1, r0 169; ARM7-NEXT: bx lr 170; 171; NODSP-LABEL: SMMLS: 172; NODSP: @ %bb.0: @ %entry 173; NODSP-NEXT: smull r1, r2, r2, r1 174; NODSP-NEXT: rsbs r1, r1, #0 175; NODSP-NEXT: sbcs r0, r2 176; NODSP-NEXT: bx lr 177entry: 178 %conv5 = zext i32 %a to i64 179 %shl = shl nuw i64 %conv5, 32 180 %conv1 = sext i32 %b to i64 181 %conv2 = sext i32 %c to i64 182 %mul = mul nsw i64 %conv2, %conv1 183 %sub = sub nsw i64 %shl, %mul 184 %0 = lshr i64 %sub, 32 185 %conv3 = trunc i64 %0 to i32 186 ret i32 %conv3 187} 188 189define hidden i32 @NOT_SMMLS(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 190; DSP-LABEL: NOT_SMMLS: 191; DSP: @ %bb.0: @ %entry 192; DSP-NEXT: smmul r1, r2, r1 193; DSP-NEXT: subs r0, r0, r1 194; DSP-NEXT: bx lr 195; 196; ARM7-LABEL: NOT_SMMLS: 197; ARM7: @ %bb.0: @ %entry 198; ARM7-NEXT: smmul r1, r2, r1 199; ARM7-NEXT: sub r0, r0, r1 200; ARM7-NEXT: bx lr 201; 202; NODSP-LABEL: NOT_SMMLS: 203; NODSP: @ %bb.0: @ %entry 204; NODSP-NEXT: smull r1, r2, r2, r1 205; NODSP-NEXT: subs r0, r0, r2 206; NODSP-NEXT: bx lr 207entry: 208 %conv = sext i32 %b to i64 209 %conv1 = sext i32 %c to i64 210 %mul = mul nsw i64 %conv1, %conv 211 %0 = lshr i64 %mul, 32 212 %conv2 = trunc i64 %0 to i32 213 %sub = sub nsw i32 %a, %conv2 214 ret i32 %sub 215} 216 217define hidden i32 @SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 218; DSP-LABEL: SMMLA: 219; DSP: @ %bb.0: @ %entry 220; DSP-NEXT: smmla r0, r1, r2, r0 221; DSP-NEXT: bx lr 222; 223; ARM7-LABEL: SMMLA: 224; ARM7: @ %bb.0: @ %entry 225; ARM7-NEXT: smmla r0, r2, r1, r0 226; ARM7-NEXT: bx lr 227; 228; NODSP-LABEL: SMMLA: 229; NODSP: @ %bb.0: @ %entry 230; NODSP-NEXT: smull r1, r2, r2, r1 231; NODSP-NEXT: add r0, r2 232; NODSP-NEXT: bx lr 233entry: 234 %conv = sext i32 %b to i64 235 %conv1 = sext i32 %c to i64 236 %mul = mul nsw i64 %conv1, %conv 237 %0 = lshr i64 %mul, 32 238 %conv2 = trunc i64 %0 to i32 239 %add = add nsw i32 %conv2, %a 240 ret i32 %add 241} 242 243define hidden i32 @SMMLAR(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 244; DSP-LABEL: SMMLAR: 245; DSP: @ %bb.0: @ %entry 246; DSP-NEXT: smmlar r0, r2, r1, r0 247; DSP-NEXT: bx lr 248; 249; ARM7-LABEL: SMMLAR: 250; ARM7: @ %bb.0: @ %entry 251; ARM7-NEXT: smmlar r0, r2, r1, r0 252; ARM7-NEXT: bx lr 253; 254; NODSP-LABEL: SMMLAR: 255; NODSP: @ %bb.0: @ %entry 256; NODSP-NEXT: mov.w r3, #-2147483648 257; NODSP-NEXT: smlal r3, r0, r2, r1 258; NODSP-NEXT: bx lr 259entry: 260 %conv7 = zext i32 %a to i64 261 %shl = shl nuw i64 %conv7, 32 262 %conv1 = sext i32 %b to i64 263 %conv2 = sext i32 %c to i64 264 %mul = mul nsw i64 %conv2, %conv1 265 %add = or i64 %shl, 2147483648 266 %add3 = add i64 %add, %mul 267 %0 = lshr i64 %add3, 32 268 %conv4 = trunc i64 %0 to i32 269 ret i32 %conv4 270} 271 272define hidden i32 @NOT_SMMLA(i32 %a, i32 %b, i32 %c) local_unnamed_addr { 273; DSP-LABEL: NOT_SMMLA: 274; DSP: @ %bb.0: @ %entry 275; DSP-NEXT: smmul r1, r2, r1 276; DSP-NEXT: eor r1, r1, #-2147483648 277; DSP-NEXT: add r0, r1 278; DSP-NEXT: bx lr 279; 280; ARM7-LABEL: NOT_SMMLA: 281; ARM7: @ %bb.0: @ %entry 282; ARM7-NEXT: smmul r1, r2, r1 283; ARM7-NEXT: eor r1, r1, #-2147483648 284; ARM7-NEXT: add r0, r1, r0 285; ARM7-NEXT: bx lr 286; 287; NODSP-LABEL: NOT_SMMLA: 288; NODSP: @ %bb.0: @ %entry 289; NODSP-NEXT: smull r1, r2, r2, r1 290; NODSP-NEXT: eor r1, r2, #-2147483648 291; NODSP-NEXT: add r0, r1 292; NODSP-NEXT: bx lr 293entry: 294 %conv = sext i32 %b to i64 295 %conv1 = sext i32 %c to i64 296 %mul = mul nsw i64 %conv1, %conv 297 %0 = lshr i64 %mul, 32 298 %conv2 = trunc i64 %0 to i32 299 %add = xor i32 %conv2, -2147483648 300 %add3 = add i32 %add, %a 301 ret i32 %add3 302} 303