1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac -mattr=+m -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32XTHEADMAC 4; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac -mattr=+m -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64XTHEADMAC 6 7define i32 @mula_i32(i32 %a, i32 %b, i32 %c) { 8; RV32XTHEADMAC-LABEL: mula_i32: 9; RV32XTHEADMAC: # %bb.0: 10; RV32XTHEADMAC-NEXT: th.mula a0, a1, a2 11; RV32XTHEADMAC-NEXT: ret 12; 13; RV64XTHEADMAC-LABEL: mula_i32: 14; RV64XTHEADMAC: # %bb.0: 15; RV64XTHEADMAC-NEXT: th.mulaw a0, a1, a2 16; RV64XTHEADMAC-NEXT: ret 17 %d = mul i32 %b, %c 18 %e = add i32 %a, %d 19 ret i32 %e 20} 21 22define i32 @muls_i32(i32 %a, i32 %b, i32 %c) { 23; RV32XTHEADMAC-LABEL: muls_i32: 24; RV32XTHEADMAC: # %bb.0: 25; RV32XTHEADMAC-NEXT: th.muls a0, a1, a2 26; RV32XTHEADMAC-NEXT: ret 27; 28; RV64XTHEADMAC-LABEL: muls_i32: 29; RV64XTHEADMAC: # %bb.0: 30; RV64XTHEADMAC-NEXT: th.mulsw a0, a1, a2 31; RV64XTHEADMAC-NEXT: ret 32 %d = mul i32 %b, %c 33 %e = sub i32 %a, %d 34 ret i32 %e 35} 36 37define i64 @mula_i64(i64 %a, i64 %b, i64 %c) { 38; RV32XTHEADMAC-LABEL: mula_i64: 39; RV32XTHEADMAC: # %bb.0: 40; RV32XTHEADMAC-NEXT: mulhu a6, a2, a4 41; RV32XTHEADMAC-NEXT: th.mula a6, a2, a5 42; RV32XTHEADMAC-NEXT: mv a5, a0 43; RV32XTHEADMAC-NEXT: th.mula a5, a2, a4 44; RV32XTHEADMAC-NEXT: th.mula a6, a3, a4 45; RV32XTHEADMAC-NEXT: sltu a0, a5, a0 46; RV32XTHEADMAC-NEXT: add a0, a1, a0 47; RV32XTHEADMAC-NEXT: add a1, a0, a6 48; RV32XTHEADMAC-NEXT: mv a0, a5 49; RV32XTHEADMAC-NEXT: ret 50; 51; RV64XTHEADMAC-LABEL: mula_i64: 52; RV64XTHEADMAC: # %bb.0: 53; RV64XTHEADMAC-NEXT: th.mula a0, a1, a2 54; RV64XTHEADMAC-NEXT: ret 55 %d = mul i64 %b, %c 56 %f = add i64 %a, %d 57 ret i64 %f 58} 59 60define i64 @mulaw_i64(i32 %a, i32 %b, i32 %c) { 61; RV32XTHEADMAC-LABEL: mulaw_i64: 62; RV32XTHEADMAC: # %bb.0: 63; RV32XTHEADMAC-NEXT: th.mula a0, a1, a2 64; RV32XTHEADMAC-NEXT: srai a1, a0, 31 65; RV32XTHEADMAC-NEXT: ret 66; 67; RV64XTHEADMAC-LABEL: mulaw_i64: 68; RV64XTHEADMAC: # %bb.0: 69; RV64XTHEADMAC-NEXT: th.mulaw a0, a1, a2 70; RV64XTHEADMAC-NEXT: ret 71 %d = mul i32 %b, %c 72 %e = add i32 %a, %d 73 %f = sext i32 %e to i64 74 ret i64 %f 75} 76 77define i64 @mulah_i64(i32 %a, i16 %b, i16 %c) { 78; RV32XTHEADMAC-LABEL: mulah_i64: 79; RV32XTHEADMAC: # %bb.0: 80; RV32XTHEADMAC-NEXT: th.mulah a0, a1, a2 81; RV32XTHEADMAC-NEXT: srai a1, a0, 31 82; RV32XTHEADMAC-NEXT: ret 83; 84; RV64XTHEADMAC-LABEL: mulah_i64: 85; RV64XTHEADMAC: # %bb.0: 86; RV64XTHEADMAC-NEXT: th.mulah a0, a1, a2 87; RV64XTHEADMAC-NEXT: ret 88 %d = sext i16 %b to i32 89 %e = sext i16 %c to i32 90 %f = mul i32 %d, %e 91 %g = add i32 %a, %f 92 %h = sext i32 %g to i64 93 ret i64 %h 94} 95 96define i64 @muls_i64(i64 %a, i64 %b, i64 %c) { 97; RV32XTHEADMAC-LABEL: muls_i64: 98; RV32XTHEADMAC: # %bb.0: 99; RV32XTHEADMAC-NEXT: mulhu a6, a2, a4 100; RV32XTHEADMAC-NEXT: th.mula a6, a2, a5 101; RV32XTHEADMAC-NEXT: mul a5, a2, a4 102; RV32XTHEADMAC-NEXT: sltu a5, a0, a5 103; RV32XTHEADMAC-NEXT: th.muls a0, a2, a4 104; RV32XTHEADMAC-NEXT: th.mula a6, a3, a4 105; RV32XTHEADMAC-NEXT: sub a1, a1, a5 106; RV32XTHEADMAC-NEXT: sub a1, a1, a6 107; RV32XTHEADMAC-NEXT: ret 108; 109; RV64XTHEADMAC-LABEL: muls_i64: 110; RV64XTHEADMAC: # %bb.0: 111; RV64XTHEADMAC-NEXT: th.muls a0, a1, a2 112; RV64XTHEADMAC-NEXT: ret 113 %d = mul i64 %b, %c 114 %f = sub i64 %a, %d 115 ret i64 %f 116} 117 118define i64 @mulsw_i64(i32 %a, i32 %b, i32 %c) { 119; RV32XTHEADMAC-LABEL: mulsw_i64: 120; RV32XTHEADMAC: # %bb.0: 121; RV32XTHEADMAC-NEXT: th.muls a0, a1, a2 122; RV32XTHEADMAC-NEXT: srai a1, a0, 31 123; RV32XTHEADMAC-NEXT: ret 124; 125; RV64XTHEADMAC-LABEL: mulsw_i64: 126; RV64XTHEADMAC: # %bb.0: 127; RV64XTHEADMAC-NEXT: th.mulsw a0, a1, a2 128; RV64XTHEADMAC-NEXT: ret 129 %d = mul i32 %b, %c 130 %e = sub i32 %a, %d 131 %f = sext i32 %e to i64 132 ret i64 %f 133} 134 135define i64 @mulsh_i64(i32 %a, i16 %b, i16 %c) { 136; RV32XTHEADMAC-LABEL: mulsh_i64: 137; RV32XTHEADMAC: # %bb.0: 138; RV32XTHEADMAC-NEXT: th.mulsh a0, a1, a2 139; RV32XTHEADMAC-NEXT: srai a1, a0, 31 140; RV32XTHEADMAC-NEXT: ret 141; 142; RV64XTHEADMAC-LABEL: mulsh_i64: 143; RV64XTHEADMAC: # %bb.0: 144; RV64XTHEADMAC-NEXT: th.mulsh a0, a1, a2 145; RV64XTHEADMAC-NEXT: ret 146 %d = sext i16 %b to i32 147 %e = sext i16 %c to i32 148 %f = mul i32 %d, %e 149 %g = sub i32 %a, %f 150 %h = sext i32 %g to i64 151 ret i64 %h 152} 153 154define i32 @commutative1(i32 %A, i32 %B, i32 %C) { 155; RV32XTHEADMAC-LABEL: commutative1: 156; RV32XTHEADMAC: # %bb.0: 157; RV32XTHEADMAC-NEXT: th.mula a2, a1, a0 158; RV32XTHEADMAC-NEXT: mv a0, a2 159; RV32XTHEADMAC-NEXT: ret 160; 161; RV64XTHEADMAC-LABEL: commutative1: 162; RV64XTHEADMAC: # %bb.0: 163; RV64XTHEADMAC-NEXT: th.mulaw a2, a1, a0 164; RV64XTHEADMAC-NEXT: mv a0, a2 165; RV64XTHEADMAC-NEXT: ret 166 %mul = mul nsw i32 %B, %A 167 %add = add i32 %mul, %C 168 ret i32 %add 169} 170 171define i32 @commutative2(i32 %A, i32 %B, i32 %C) { 172; RV32XTHEADMAC-LABEL: commutative2: 173; RV32XTHEADMAC: # %bb.0: 174; RV32XTHEADMAC-NEXT: th.mula a0, a1, a2 175; RV32XTHEADMAC-NEXT: ret 176; 177; RV64XTHEADMAC-LABEL: commutative2: 178; RV64XTHEADMAC: # %bb.0: 179; RV64XTHEADMAC-NEXT: th.mulaw a0, a1, a2 180; RV64XTHEADMAC-NEXT: ret 181 %mul = mul nsw i32 %B, %C 182 %add = add i32 %mul, %A 183 ret i32 %add 184} 185 186define i32 @commutative3(i32 %A, i32 %B, i32 %C) { 187; RV32XTHEADMAC-LABEL: commutative3: 188; RV32XTHEADMAC: # %bb.0: 189; RV32XTHEADMAC-NEXT: th.mula a1, a2, a0 190; RV32XTHEADMAC-NEXT: mv a0, a1 191; RV32XTHEADMAC-NEXT: ret 192; 193; RV64XTHEADMAC-LABEL: commutative3: 194; RV64XTHEADMAC: # %bb.0: 195; RV64XTHEADMAC-NEXT: th.mulaw a1, a2, a0 196; RV64XTHEADMAC-NEXT: mv a0, a1 197; RV64XTHEADMAC-NEXT: ret 198 %mul = mul nsw i32 %C, %A 199 %add = add i32 %mul, %B 200 ret i32 %add 201} 202