1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefixes=32 3; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefixes=32 4; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefixes=32R6 5; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP 6; RUN: llc -march=mips -mcpu=mips64 -target-abi n64 < %s | FileCheck %s -check-prefixes=64 7; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s | FileCheck %s -check-prefixes=64 8; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s | FileCheck %s -check-prefixes=64R6 9; RUN: llc -march=mips -mattr=mips16 < %s | FileCheck %s -check-prefixes=16 10 11define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone { 12; 32-LABEL: madd1: 13; 32: # %bb.0: # %entry 14; 32-NEXT: sra $1, $6, 31 15; 32-NEXT: mtlo $6 16; 32-NEXT: mthi $1 17; 32-NEXT: madd $5, $4 18; 32-NEXT: mfhi $2 19; 32-NEXT: jr $ra 20; 32-NEXT: mflo $3 21; 22; 32R6-LABEL: madd1: 23; 32R6: # %bb.0: # %entry 24; 32R6-NEXT: mul $1, $5, $4 25; 32R6-NEXT: addu $3, $1, $6 26; 32R6-NEXT: sltu $1, $3, $1 27; 32R6-NEXT: muh $2, $5, $4 28; 32R6-NEXT: sra $4, $6, 31 29; 32R6-NEXT: addu $2, $2, $4 30; 32R6-NEXT: jr $ra 31; 32R6-NEXT: addu $2, $2, $1 32; 33; DSP-LABEL: madd1: 34; DSP: # %bb.0: # %entry 35; DSP-NEXT: sra $1, $6, 31 36; DSP-NEXT: mtlo $6, $ac0 37; DSP-NEXT: mthi $1, $ac0 38; DSP-NEXT: madd $ac0, $5, $4 39; DSP-NEXT: mfhi $2, $ac0 40; DSP-NEXT: jr $ra 41; DSP-NEXT: mflo $3, $ac0 42; 43; 64-LABEL: madd1: 44; 64: # %bb.0: # %entry 45; 64-NEXT: sll $1, $4, 0 46; 64-NEXT: sll $2, $5, 0 47; 64-NEXT: dmult $2, $1 48; 64-NEXT: mflo $1 49; 64-NEXT: sll $2, $6, 0 50; 64-NEXT: jr $ra 51; 64-NEXT: daddu $2, $1, $2 52; 53; 64R6-LABEL: madd1: 54; 64R6: # %bb.0: # %entry 55; 64R6-NEXT: sll $1, $4, 0 56; 64R6-NEXT: sll $2, $5, 0 57; 64R6-NEXT: dmul $1, $2, $1 58; 64R6-NEXT: sll $2, $6, 0 59; 64R6-NEXT: jr $ra 60; 64R6-NEXT: daddu $2, $1, $2 61; 62; 16-LABEL: madd1: 63; 16: # %bb.0: # %entry 64; 16-NEXT: mult $5, $4 65; 16-NEXT: mflo $2 66; 16-NEXT: mfhi $3 67; 16-NEXT: sra $4, $6, 31 68; 16-NEXT: addu $4, $3, $4 69; 16-NEXT: addu $3, $2, $6 70; 16-NEXT: sltu $3, $2 71; 16-NEXT: move $2, $24 72; 16-NEXT: addu $2, $4, $2 73; 16-NEXT: jrc $ra 74entry: 75 %conv = sext i32 %a to i64 76 %conv2 = sext i32 %b to i64 77 %mul = mul nsw i64 %conv2, %conv 78 %conv4 = sext i32 %c to i64 79 %add = add nsw i64 %mul, %conv4 80 ret i64 %add 81} 82 83define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone { 84; 32-LABEL: madd2: 85; 32: # %bb.0: # %entry 86; 32-NEXT: addiu $1, $zero, 0 87; 32-NEXT: mtlo $6 88; 32-NEXT: mthi $1 89; 32-NEXT: maddu $5, $4 90; 32-NEXT: mfhi $2 91; 32-NEXT: jr $ra 92; 32-NEXT: mflo $3 93; 94; 32R6-LABEL: madd2: 95; 32R6: # %bb.0: # %entry 96; 32R6-NEXT: mul $1, $5, $4 97; 32R6-NEXT: addu $3, $1, $6 98; 32R6-NEXT: sltu $1, $3, $1 99; 32R6-NEXT: muhu $2, $5, $4 100; 32R6-NEXT: jr $ra 101; 32R6-NEXT: addu $2, $2, $1 102; 103; DSP-LABEL: madd2: 104; DSP: # %bb.0: # %entry 105; DSP-NEXT: addiu $1, $zero, 0 106; DSP-NEXT: mtlo $6, $ac0 107; DSP-NEXT: mthi $1, $ac0 108; DSP-NEXT: maddu $ac0, $5, $4 109; DSP-NEXT: mfhi $2, $ac0 110; DSP-NEXT: jr $ra 111; DSP-NEXT: mflo $3, $ac0 112; 113; 64-LABEL: madd2: 114; 64: # %bb.0: # %entry 115; 64-NEXT: dmult $5, $4 116; 64-NEXT: mflo $1 117; 64-NEXT: jr $ra 118; 64-NEXT: daddu $2, $1, $6 119; 120; 64R6-LABEL: madd2: 121; 64R6: # %bb.0: # %entry 122; 64R6-NEXT: dmul $1, $5, $4 123; 64R6-NEXT: jr $ra 124; 64R6-NEXT: daddu $2, $1, $6 125; 126; 16-LABEL: madd2: 127; 16: # %bb.0: # %entry 128; 16-NEXT: multu $5, $4 129; 16-NEXT: mflo $2 130; 16-NEXT: mfhi $4 131; 16-NEXT: addu $3, $2, $6 132; 16-NEXT: sltu $3, $2 133; 16-NEXT: move $2, $24 134; 16-NEXT: addu $2, $4, $2 135; 16-NEXT: jrc $ra 136entry: 137 %conv = zext i32 %a to i64 138 %conv2 = zext i32 %b to i64 139 %mul = mul nsw i64 %conv2, %conv 140 %conv4 = zext i32 %c to i64 141 %add = add nsw i64 %mul, %conv4 142 ret i64 %add 143} 144 145define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone { 146; 32-LABEL: madd3: 147; 32: # %bb.0: # %entry 148; 32-NEXT: mtlo $7 149; 32-NEXT: mthi $6 150; 32-NEXT: madd $5, $4 151; 32-NEXT: mfhi $2 152; 32-NEXT: jr $ra 153; 32-NEXT: mflo $3 154; 155; 32R6-LABEL: madd3: 156; 32R6: # %bb.0: # %entry 157; 32R6-NEXT: mul $1, $5, $4 158; 32R6-NEXT: addu $3, $1, $7 159; 32R6-NEXT: sltu $1, $3, $1 160; 32R6-NEXT: muh $2, $5, $4 161; 32R6-NEXT: addu $2, $2, $6 162; 32R6-NEXT: jr $ra 163; 32R6-NEXT: addu $2, $2, $1 164; 165; DSP-LABEL: madd3: 166; DSP: # %bb.0: # %entry 167; DSP-NEXT: mtlo $7, $ac0 168; DSP-NEXT: mthi $6, $ac0 169; DSP-NEXT: madd $ac0, $5, $4 170; DSP-NEXT: mfhi $2, $ac0 171; DSP-NEXT: jr $ra 172; DSP-NEXT: mflo $3, $ac0 173; 174; 64-LABEL: madd3: 175; 64: # %bb.0: # %entry 176; 64-NEXT: sll $1, $4, 0 177; 64-NEXT: sll $2, $5, 0 178; 64-NEXT: dmult $2, $1 179; 64-NEXT: mflo $1 180; 64-NEXT: jr $ra 181; 64-NEXT: daddu $2, $1, $6 182; 183; 64R6-LABEL: madd3: 184; 64R6: # %bb.0: # %entry 185; 64R6-NEXT: sll $1, $4, 0 186; 64R6-NEXT: sll $2, $5, 0 187; 64R6-NEXT: dmul $1, $2, $1 188; 64R6-NEXT: jr $ra 189; 64R6-NEXT: daddu $2, $1, $6 190; 191; 16-LABEL: madd3: 192; 16: # %bb.0: # %entry 193; 16-NEXT: mult $5, $4 194; 16-NEXT: mflo $2 195; 16-NEXT: mfhi $3 196; 16-NEXT: addu $4, $3, $6 197; 16-NEXT: addu $3, $2, $7 198; 16-NEXT: sltu $3, $2 199; 16-NEXT: move $2, $24 200; 16-NEXT: addu $2, $4, $2 201; 16-NEXT: jrc $ra 202entry: 203 %conv = sext i32 %a to i64 204 %conv2 = sext i32 %b to i64 205 %mul = mul nsw i64 %conv2, %conv 206 %add = add nsw i64 %mul, %c 207 ret i64 %add 208} 209 210define i32 @madd4(i32 %a, i32 %b, i32 %c) { 211; 32-LABEL: madd4: 212; 32: # %bb.0: # %entry 213; 32-NEXT: mul $1, $4, $5 214; 32-NEXT: jr $ra 215; 32-NEXT: addu $2, $6, $1 216; 217; 32R6-LABEL: madd4: 218; 32R6: # %bb.0: # %entry 219; 32R6-NEXT: mul $1, $4, $5 220; 32R6-NEXT: jr $ra 221; 32R6-NEXT: addu $2, $6, $1 222; 223; DSP-LABEL: madd4: 224; DSP: # %bb.0: # %entry 225; DSP-NEXT: mul $1, $4, $5 226; DSP-NEXT: jr $ra 227; DSP-NEXT: addu $2, $6, $1 228; 229; 64-LABEL: madd4: 230; 64: # %bb.0: # %entry 231; 64-NEXT: sll $1, $5, 0 232; 64-NEXT: sll $2, $4, 0 233; 64-NEXT: mul $1, $2, $1 234; 64-NEXT: sll $2, $6, 0 235; 64-NEXT: jr $ra 236; 64-NEXT: addu $2, $2, $1 237; 238; 64R6-LABEL: madd4: 239; 64R6: # %bb.0: # %entry 240; 64R6-NEXT: sll $1, $5, 0 241; 64R6-NEXT: sll $2, $4, 0 242; 64R6-NEXT: mul $1, $2, $1 243; 64R6-NEXT: sll $2, $6, 0 244; 64R6-NEXT: jr $ra 245; 64R6-NEXT: addu $2, $2, $1 246; 247; 16-LABEL: madd4: 248; 16: # %bb.0: # %entry 249; 16-NEXT: mult $4, $5 250; 16-NEXT: mflo $2 251; 16-NEXT: addu $2, $6, $2 252; 16-NEXT: jrc $ra 253entry: 254 %mul = mul nsw i32 %a, %b 255 %add = add nsw i32 %c, %mul 256 257 ret i32 %add 258} 259 260define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone { 261; 32-LABEL: msub1: 262; 32: # %bb.0: # %entry 263; 32-NEXT: sra $1, $6, 31 264; 32-NEXT: mtlo $6 265; 32-NEXT: mthi $1 266; 32-NEXT: msub $5, $4 267; 32-NEXT: mfhi $2 268; 32-NEXT: jr $ra 269; 32-NEXT: mflo $3 270; 271; 32R6-LABEL: msub1: 272; 32R6: # %bb.0: # %entry 273; 32R6-NEXT: mul $1, $5, $4 274; 32R6-NEXT: sltu $2, $6, $1 275; 32R6-NEXT: muh $3, $5, $4 276; 32R6-NEXT: sra $4, $6, 31 277; 32R6-NEXT: subu $3, $4, $3 278; 32R6-NEXT: subu $2, $3, $2 279; 32R6-NEXT: jr $ra 280; 32R6-NEXT: subu $3, $6, $1 281; 282; DSP-LABEL: msub1: 283; DSP: # %bb.0: # %entry 284; DSP-NEXT: sra $1, $6, 31 285; DSP-NEXT: mtlo $6, $ac0 286; DSP-NEXT: mthi $1, $ac0 287; DSP-NEXT: msub $ac0, $5, $4 288; DSP-NEXT: mfhi $2, $ac0 289; DSP-NEXT: jr $ra 290; DSP-NEXT: mflo $3, $ac0 291; 292; 64-LABEL: msub1: 293; 64: # %bb.0: # %entry 294; 64-NEXT: sll $1, $4, 0 295; 64-NEXT: sll $2, $5, 0 296; 64-NEXT: dmult $2, $1 297; 64-NEXT: mflo $1 298; 64-NEXT: sll $2, $6, 0 299; 64-NEXT: jr $ra 300; 64-NEXT: dsubu $2, $2, $1 301; 302; 64R6-LABEL: msub1: 303; 64R6: # %bb.0: # %entry 304; 64R6-NEXT: sll $1, $4, 0 305; 64R6-NEXT: sll $2, $5, 0 306; 64R6-NEXT: dmul $1, $2, $1 307; 64R6-NEXT: sll $2, $6, 0 308; 64R6-NEXT: jr $ra 309; 64R6-NEXT: dsubu $2, $2, $1 310; 311; 16-LABEL: msub1: 312; 16: # %bb.0: # %entry 313; 16-NEXT: mult $5, $4 314; 16-NEXT: mflo $2 315; 16-NEXT: mfhi $4 316; 16-NEXT: subu $3, $6, $2 317; 16-NEXT: sltu $6, $2 318; 16-NEXT: move $2, $24 319; 16-NEXT: sra $5, $6, 31 320; 16-NEXT: subu $4, $5, $4 321; 16-NEXT: subu $2, $4, $2 322; 16-NEXT: jrc $ra 323entry: 324 %conv = sext i32 %c to i64 325 %conv2 = sext i32 %a to i64 326 %conv4 = sext i32 %b to i64 327 %mul = mul nsw i64 %conv4, %conv2 328 %sub = sub nsw i64 %conv, %mul 329 ret i64 %sub 330} 331 332define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone { 333; 32-LABEL: msub2: 334; 32: # %bb.0: # %entry 335; 32-NEXT: addiu $1, $zero, 0 336; 32-NEXT: mtlo $6 337; 32-NEXT: mthi $1 338; 32-NEXT: msubu $5, $4 339; 32-NEXT: mfhi $2 340; 32-NEXT: jr $ra 341; 32-NEXT: mflo $3 342; 343; 32R6-LABEL: msub2: 344; 32R6: # %bb.0: # %entry 345; 32R6-NEXT: muhu $1, $5, $4 346; 32R6-NEXT: mul $3, $5, $4 347; 32R6-NEXT: sltu $2, $6, $3 348; 32R6-NEXT: addu $1, $1, $2 349; 32R6-NEXT: negu $2, $1 350; 32R6-NEXT: jr $ra 351; 32R6-NEXT: subu $3, $6, $3 352; 353; DSP-LABEL: msub2: 354; DSP: # %bb.0: # %entry 355; DSP-NEXT: addiu $1, $zero, 0 356; DSP-NEXT: mtlo $6, $ac0 357; DSP-NEXT: mthi $1, $ac0 358; DSP-NEXT: msubu $ac0, $5, $4 359; DSP-NEXT: mfhi $2, $ac0 360; DSP-NEXT: jr $ra 361; DSP-NEXT: mflo $3, $ac0 362; 363; 64-LABEL: msub2: 364; 64: # %bb.0: # %entry 365; 64-NEXT: dmult $5, $4 366; 64-NEXT: mflo $1 367; 64-NEXT: jr $ra 368; 64-NEXT: dsubu $2, $6, $1 369; 370; 64R6-LABEL: msub2: 371; 64R6: # %bb.0: # %entry 372; 64R6-NEXT: dmul $1, $5, $4 373; 64R6-NEXT: jr $ra 374; 64R6-NEXT: dsubu $2, $6, $1 375; 376; 16-LABEL: msub2: 377; 16: # %bb.0: # %entry 378; 16-NEXT: multu $5, $4 379; 16-NEXT: mflo $2 380; 16-NEXT: mfhi $3 381; 16-NEXT: sltu $6, $2 382; 16-NEXT: move $4, $24 383; 16-NEXT: addu $4, $3, $4 384; 16-NEXT: subu $3, $6, $2 385; 16-NEXT: neg $2, $4 386; 16-NEXT: jrc $ra 387entry: 388 %conv = zext i32 %c to i64 389 %conv2 = zext i32 %a to i64 390 %conv4 = zext i32 %b to i64 391 %mul = mul nsw i64 %conv4, %conv2 392 %sub = sub nsw i64 %conv, %mul 393 ret i64 %sub 394} 395 396define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone { 397; 32-LABEL: msub3: 398; 32: # %bb.0: # %entry 399; 32-NEXT: mtlo $7 400; 32-NEXT: mthi $6 401; 32-NEXT: msub $5, $4 402; 32-NEXT: mfhi $2 403; 32-NEXT: jr $ra 404; 32-NEXT: mflo $3 405; 406; 32R6-LABEL: msub3: 407; 32R6: # %bb.0: # %entry 408; 32R6-NEXT: mul $1, $5, $4 409; 32R6-NEXT: sltu $2, $7, $1 410; 32R6-NEXT: muh $3, $5, $4 411; 32R6-NEXT: subu $3, $6, $3 412; 32R6-NEXT: subu $2, $3, $2 413; 32R6-NEXT: jr $ra 414; 32R6-NEXT: subu $3, $7, $1 415; 416; DSP-LABEL: msub3: 417; DSP: # %bb.0: # %entry 418; DSP-NEXT: mtlo $7, $ac0 419; DSP-NEXT: mthi $6, $ac0 420; DSP-NEXT: msub $ac0, $5, $4 421; DSP-NEXT: mfhi $2, $ac0 422; DSP-NEXT: jr $ra 423; DSP-NEXT: mflo $3, $ac0 424; 425; 64-LABEL: msub3: 426; 64: # %bb.0: # %entry 427; 64-NEXT: sll $1, $4, 0 428; 64-NEXT: sll $2, $5, 0 429; 64-NEXT: dmult $2, $1 430; 64-NEXT: mflo $1 431; 64-NEXT: jr $ra 432; 64-NEXT: dsubu $2, $6, $1 433; 434; 64R6-LABEL: msub3: 435; 64R6: # %bb.0: # %entry 436; 64R6-NEXT: sll $1, $4, 0 437; 64R6-NEXT: sll $2, $5, 0 438; 64R6-NEXT: dmul $1, $2, $1 439; 64R6-NEXT: jr $ra 440; 64R6-NEXT: dsubu $2, $6, $1 441; 442; 16-LABEL: msub3: 443; 16: # %bb.0: # %entry 444; 16-NEXT: mult $5, $4 445; 16-NEXT: mflo $2 446; 16-NEXT: mfhi $4 447; 16-NEXT: subu $3, $7, $2 448; 16-NEXT: sltu $7, $2 449; 16-NEXT: move $2, $24 450; 16-NEXT: subu $4, $6, $4 451; 16-NEXT: subu $2, $4, $2 452; 16-NEXT: jrc $ra 453entry: 454 %conv = sext i32 %a to i64 455 %conv3 = sext i32 %b to i64 456 %mul = mul nsw i64 %conv3, %conv 457 %sub = sub nsw i64 %c, %mul 458 ret i64 %sub 459} 460 461define i32 @msub4(i32 %a, i32 %b, i32 %c) { 462; 32-LABEL: msub4: 463; 32: # %bb.0: # %entry 464; 32-NEXT: mul $1, $4, $5 465; 32-NEXT: jr $ra 466; 32-NEXT: subu $2, $6, $1 467; 468; 32R6-LABEL: msub4: 469; 32R6: # %bb.0: # %entry 470; 32R6-NEXT: mul $1, $4, $5 471; 32R6-NEXT: jr $ra 472; 32R6-NEXT: subu $2, $6, $1 473; 474; DSP-LABEL: msub4: 475; DSP: # %bb.0: # %entry 476; DSP-NEXT: mul $1, $4, $5 477; DSP-NEXT: jr $ra 478; DSP-NEXT: subu $2, $6, $1 479; 480; 64-LABEL: msub4: 481; 64: # %bb.0: # %entry 482; 64-NEXT: sll $1, $5, 0 483; 64-NEXT: sll $2, $4, 0 484; 64-NEXT: mul $1, $2, $1 485; 64-NEXT: sll $2, $6, 0 486; 64-NEXT: jr $ra 487; 64-NEXT: subu $2, $2, $1 488; 489; 64R6-LABEL: msub4: 490; 64R6: # %bb.0: # %entry 491; 64R6-NEXT: sll $1, $5, 0 492; 64R6-NEXT: sll $2, $4, 0 493; 64R6-NEXT: mul $1, $2, $1 494; 64R6-NEXT: sll $2, $6, 0 495; 64R6-NEXT: jr $ra 496; 64R6-NEXT: subu $2, $2, $1 497; 498; 16-LABEL: msub4: 499; 16: # %bb.0: # %entry 500; 16-NEXT: mult $4, $5 501; 16-NEXT: mflo $2 502; 16-NEXT: subu $2, $6, $2 503; 16-NEXT: jrc $ra 504entry: 505 %mul = mul nsw i32 %a, %b 506 %sub = sub nsw i32 %c, %mul 507 508 ret i32 %sub 509} 510