1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd -verify-machineinstrs | FileCheck %s 3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -verify-machineinstrs | FileCheck --check-prefix=NF %s 4 5define i16 @mul16rr(i16 noundef %a, i16 noundef %b) { 6; CHECK-LABEL: mul16rr: 7; CHECK: # %bb.0: # %entry 8; CHECK-NEXT: imull %esi, %edi, %eax 9; CHECK-NEXT: # kill: def $ax killed $ax killed $eax 10; CHECK-NEXT: retq 11; 12; NF-LABEL: mul16rr: 13; NF: # %bb.0: # %entry 14; NF-NEXT: {nf} imull %esi, %edi, %eax 15; NF-NEXT: # kill: def $ax killed $ax killed $eax 16; NF-NEXT: retq 17entry: 18 %mul = mul i16 %a, %b 19 ret i16 %mul 20} 21 22define i32 @mul32rr(i32 noundef %a, i32 noundef %b) { 23; CHECK-LABEL: mul32rr: 24; CHECK: # %bb.0: # %entry 25; CHECK-NEXT: imull %esi, %edi, %eax 26; CHECK-NEXT: retq 27; 28; NF-LABEL: mul32rr: 29; NF: # %bb.0: # %entry 30; NF-NEXT: {nf} imull %esi, %edi, %eax 31; NF-NEXT: retq 32entry: 33 %mul = mul i32 %a, %b 34 ret i32 %mul 35} 36 37define i64 @mul64rr(i64 noundef %a, i64 noundef %b) { 38; CHECK-LABEL: mul64rr: 39; CHECK: # %bb.0: # %entry 40; CHECK-NEXT: imulq %rsi, %rdi, %rax 41; CHECK-NEXT: retq 42; 43; NF-LABEL: mul64rr: 44; NF: # %bb.0: # %entry 45; NF-NEXT: {nf} imulq %rsi, %rdi, %rax 46; NF-NEXT: retq 47entry: 48 %mul = mul i64 %a, %b 49 ret i64 %mul 50} 51 52define i16 @smul16rr(i16 noundef %a, i16 noundef %b) { 53; CHECK-LABEL: smul16rr: 54; CHECK: # %bb.0: # %entry 55; CHECK-NEXT: imulw %si, %di, %ax 56; CHECK-NEXT: retq 57; 58; NF-LABEL: smul16rr: 59; NF: # %bb.0: # %entry 60; NF-NEXT: {nf} imulw %si, %di, %ax 61; NF-NEXT: retq 62entry: 63 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b) 64 %mul = extractvalue {i16, i1} %t, 0 65 ret i16 %mul 66} 67 68define i32 @smul32rr(i32 noundef %a, i32 noundef %b) { 69; CHECK-LABEL: smul32rr: 70; CHECK: # %bb.0: # %entry 71; CHECK-NEXT: imull %esi, %edi, %eax 72; CHECK-NEXT: retq 73; 74; NF-LABEL: smul32rr: 75; NF: # %bb.0: # %entry 76; NF-NEXT: {nf} imull %esi, %edi, %eax 77; NF-NEXT: retq 78entry: 79 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b) 80 %mul = extractvalue {i32, i1} %t, 0 81 ret i32 %mul 82} 83 84define i64 @smul64rr(i64 noundef %a, i64 noundef %b) { 85; CHECK-LABEL: smul64rr: 86; CHECK: # %bb.0: # %entry 87; CHECK-NEXT: imulq %rsi, %rdi, %rax 88; CHECK-NEXT: retq 89; 90; NF-LABEL: smul64rr: 91; NF: # %bb.0: # %entry 92; NF-NEXT: {nf} imulq %rsi, %rdi, %rax 93; NF-NEXT: retq 94entry: 95 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %a, i64 %b) 96 %mul = extractvalue {i64, i1} %t, 0 97 ret i64 %mul 98} 99 100define i16 @mul16rm(i16 noundef %a, ptr %ptr) { 101; CHECK-LABEL: mul16rm: 102; CHECK: # %bb.0: # %entry 103; CHECK-NEXT: imulw (%rsi), %di, %ax 104; CHECK-NEXT: retq 105; 106; NF-LABEL: mul16rm: 107; NF: # %bb.0: # %entry 108; NF-NEXT: {nf} imulw (%rsi), %di, %ax 109; NF-NEXT: retq 110entry: 111 %b = load i16, ptr %ptr 112 %mul = mul i16 %a, %b 113 ret i16 %mul 114} 115 116define i32 @mul32rm(i32 noundef %a, ptr %ptr) { 117; CHECK-LABEL: mul32rm: 118; CHECK: # %bb.0: # %entry 119; CHECK-NEXT: imull (%rsi), %edi, %eax 120; CHECK-NEXT: retq 121; 122; NF-LABEL: mul32rm: 123; NF: # %bb.0: # %entry 124; NF-NEXT: {nf} imull (%rsi), %edi, %eax 125; NF-NEXT: retq 126entry: 127 %b = load i32, ptr %ptr 128 %mul = mul i32 %a, %b 129 ret i32 %mul 130} 131 132define i64 @mul64rm(i64 noundef %a, ptr %ptr) { 133; CHECK-LABEL: mul64rm: 134; CHECK: # %bb.0: # %entry 135; CHECK-NEXT: imulq (%rsi), %rdi, %rax 136; CHECK-NEXT: retq 137; 138; NF-LABEL: mul64rm: 139; NF: # %bb.0: # %entry 140; NF-NEXT: {nf} imulq (%rsi), %rdi, %rax 141; NF-NEXT: retq 142entry: 143 %b = load i64, ptr %ptr 144 %mul = mul i64 %a, %b 145 ret i64 %mul 146} 147 148define i16 @smul16rm(i16 noundef %a, ptr %ptr) { 149; CHECK-LABEL: smul16rm: 150; CHECK: # %bb.0: # %entry 151; CHECK-NEXT: imulw (%rsi), %di, %ax 152; CHECK-NEXT: retq 153; 154; NF-LABEL: smul16rm: 155; NF: # %bb.0: # %entry 156; NF-NEXT: {nf} imulw (%rsi), %di, %ax 157; NF-NEXT: retq 158entry: 159 %b = load i16, ptr %ptr 160 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b) 161 %mul = extractvalue {i16, i1} %t, 0 162 ret i16 %mul 163} 164 165define i32 @smul32rm(i32 noundef %a, ptr %ptr) { 166; CHECK-LABEL: smul32rm: 167; CHECK: # %bb.0: # %entry 168; CHECK-NEXT: imull (%rsi), %edi, %eax 169; CHECK-NEXT: retq 170; 171; NF-LABEL: smul32rm: 172; NF: # %bb.0: # %entry 173; NF-NEXT: {nf} imull (%rsi), %edi, %eax 174; NF-NEXT: retq 175entry: 176 %b = load i32, ptr %ptr 177 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %a, i32 %b) 178 %mul = extractvalue {i32, i1} %t, 0 179 ret i32 %mul 180} 181 182define i64 @smul64rm(i64 noundef %a, ptr %ptr) { 183; CHECK-LABEL: smul64rm: 184; CHECK: # %bb.0: # %entry 185; CHECK-NEXT: imulq (%rsi), %rdi, %rax 186; CHECK-NEXT: retq 187; 188; NF-LABEL: smul64rm: 189; NF: # %bb.0: # %entry 190; NF-NEXT: {nf} imulq (%rsi), %rdi, %rax 191; NF-NEXT: retq 192entry: 193 %b = load i64, ptr %ptr 194 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %a, i64 %b) 195 %mul = extractvalue {i64, i1} %t, 0 196 ret i64 %mul 197} 198 199declare { i16, i1 } @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone 200declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 201declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 202