1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefix=X64 4 5declare i4 @llvm.sadd.sat.i4(i4, i4) 6declare i8 @llvm.sadd.sat.i8(i8, i8) 7declare i16 @llvm.sadd.sat.i16(i16, i16) 8declare i32 @llvm.sadd.sat.i32(i32, i32) 9declare i64 @llvm.sadd.sat.i64(i64, i64) 10 11define i32 @func32(i32 %x, i32 %y, i32 %z) nounwind { 12; X86-LABEL: func32: 13; X86: # %bb.0: 14; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 15; X86-NEXT: imull {{[0-9]+}}(%esp), %eax 16; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 17; X86-NEXT: leal (%eax,%ecx), %edx 18; X86-NEXT: sarl $31, %edx 19; X86-NEXT: addl $-2147483648, %edx # imm = 0x80000000 20; X86-NEXT: addl %ecx, %eax 21; X86-NEXT: cmovol %edx, %eax 22; X86-NEXT: retl 23; 24; X64-LABEL: func32: 25; X64: # %bb.0: 26; X64-NEXT: # kill: def $esi killed $esi def $rsi 27; X64-NEXT: # kill: def $edi killed $edi def $rdi 28; X64-NEXT: imull %edx, %esi 29; X64-NEXT: leal (%rdi,%rsi), %eax 30; X64-NEXT: sarl $31, %eax 31; X64-NEXT: addl $-2147483648, %eax # imm = 0x80000000 32; X64-NEXT: addl %edi, %esi 33; X64-NEXT: cmovnol %esi, %eax 34; X64-NEXT: retq 35 %a = mul i32 %y, %z 36 %tmp = call i32 @llvm.sadd.sat.i32(i32 %x, i32 %a) 37 ret i32 %tmp 38} 39 40define i64 @func64(i64 %x, i64 %y, i64 %z) nounwind { 41; X86-LABEL: func64: 42; X86: # %bb.0: 43; X86-NEXT: pushl %ebx 44; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 45; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 46; X86-NEXT: addl {{[0-9]+}}(%esp), %eax 47; X86-NEXT: adcl {{[0-9]+}}(%esp), %ecx 48; X86-NEXT: seto %bl 49; X86-NEXT: movl %ecx, %edx 50; X86-NEXT: sarl $31, %edx 51; X86-NEXT: testb %bl, %bl 52; X86-NEXT: cmovnel %edx, %eax 53; X86-NEXT: addl $-2147483648, %edx # imm = 0x80000000 54; X86-NEXT: testb %bl, %bl 55; X86-NEXT: cmovel %ecx, %edx 56; X86-NEXT: popl %ebx 57; X86-NEXT: retl 58; 59; X64-LABEL: func64: 60; X64: # %bb.0: 61; X64-NEXT: leaq (%rdi,%rdx), %rcx 62; X64-NEXT: sarq $63, %rcx 63; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000 64; X64-NEXT: xorq %rcx, %rax 65; X64-NEXT: addq %rdx, %rdi 66; X64-NEXT: cmovnoq %rdi, %rax 67; X64-NEXT: retq 68 %a = mul i64 %y, %z 69 %tmp = call i64 @llvm.sadd.sat.i64(i64 %x, i64 %z) 70 ret i64 %tmp 71} 72 73define signext i16 @func16(i16 signext %x, i16 signext %y, i16 signext %z) nounwind { 74; X86-LABEL: func16: 75; X86: # %bb.0: 76; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 77; X86-NEXT: imulw {{[0-9]+}}(%esp), %ax 78; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 79; X86-NEXT: movl %eax, %edx 80; X86-NEXT: addw %cx, %dx 81; X86-NEXT: movswl %dx, %edx 82; X86-NEXT: sarl $15, %edx 83; X86-NEXT: xorl $-32768, %edx # imm = 0x8000 84; X86-NEXT: addw %cx, %ax 85; X86-NEXT: cmovol %edx, %eax 86; X86-NEXT: # kill: def $ax killed $ax killed $eax 87; X86-NEXT: retl 88; 89; X64-LABEL: func16: 90; X64: # %bb.0: 91; X64-NEXT: # kill: def $esi killed $esi def $rsi 92; X64-NEXT: # kill: def $edi killed $edi def $rdi 93; X64-NEXT: imull %edx, %esi 94; X64-NEXT: leal (%rdi,%rsi), %eax 95; X64-NEXT: cwtl 96; X64-NEXT: sarl $15, %eax 97; X64-NEXT: xorl $-32768, %eax # imm = 0x8000 98; X64-NEXT: addw %si, %di 99; X64-NEXT: cmovnol %edi, %eax 100; X64-NEXT: # kill: def $ax killed $ax killed $eax 101; X64-NEXT: retq 102 %a = mul i16 %y, %z 103 %tmp = call i16 @llvm.sadd.sat.i16(i16 %x, i16 %a) 104 ret i16 %tmp 105} 106 107define signext i8 @func8(i8 signext %x, i8 signext %y, i8 signext %z) nounwind { 108; X86-LABEL: func8: 109; X86: # %bb.0: 110; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 111; X86-NEXT: mulb {{[0-9]+}}(%esp) 112; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 113; X86-NEXT: movl %eax, %edx 114; X86-NEXT: addb %cl, %dl 115; X86-NEXT: sarb $7, %dl 116; X86-NEXT: addb $-128, %dl 117; X86-NEXT: addb %cl, %al 118; X86-NEXT: movzbl %al, %ecx 119; X86-NEXT: movzbl %dl, %eax 120; X86-NEXT: cmovnol %ecx, %eax 121; X86-NEXT: # kill: def $al killed $al killed $eax 122; X86-NEXT: retl 123; 124; X64-LABEL: func8: 125; X64: # %bb.0: 126; X64-NEXT: movl %esi, %eax 127; X64-NEXT: # kill: def $edi killed $edi def $rdi 128; X64-NEXT: # kill: def $al killed $al killed $eax 129; X64-NEXT: mulb %dl 130; X64-NEXT: # kill: def $al killed $al def $rax 131; X64-NEXT: leal (%rdi,%rax), %ecx 132; X64-NEXT: sarb $7, %cl 133; X64-NEXT: addb $-128, %cl 134; X64-NEXT: addb %al, %dil 135; X64-NEXT: movzbl %dil, %edx 136; X64-NEXT: movzbl %cl, %eax 137; X64-NEXT: cmovnol %edx, %eax 138; X64-NEXT: # kill: def $al killed $al killed $eax 139; X64-NEXT: retq 140 %a = mul i8 %y, %z 141 %tmp = call i8 @llvm.sadd.sat.i8(i8 %x, i8 %a) 142 ret i8 %tmp 143} 144 145define signext i4 @func4(i4 signext %x, i4 signext %y, i4 signext %z) nounwind { 146; X86-LABEL: func4: 147; X86: # %bb.0: 148; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 149; X86-NEXT: mulb {{[0-9]+}}(%esp) 150; X86-NEXT: shlb $4, %al 151; X86-NEXT: sarb $4, %al 152; X86-NEXT: addb {{[0-9]+}}(%esp), %al 153; X86-NEXT: movzbl %al, %ecx 154; X86-NEXT: cmpb $7, %al 155; X86-NEXT: movl $7, %eax 156; X86-NEXT: cmovll %ecx, %eax 157; X86-NEXT: cmpb $-7, %al 158; X86-NEXT: movl $248, %ecx 159; X86-NEXT: cmovgel %eax, %ecx 160; X86-NEXT: movsbl %cl, %eax 161; X86-NEXT: retl 162; 163; X64-LABEL: func4: 164; X64: # %bb.0: 165; X64-NEXT: movl %esi, %eax 166; X64-NEXT: # kill: def $al killed $al killed $eax 167; X64-NEXT: mulb %dl 168; X64-NEXT: shlb $4, %al 169; X64-NEXT: sarb $4, %al 170; X64-NEXT: addb %dil, %al 171; X64-NEXT: movzbl %al, %eax 172; X64-NEXT: cmpb $7, %al 173; X64-NEXT: movl $7, %ecx 174; X64-NEXT: cmovll %eax, %ecx 175; X64-NEXT: cmpb $-7, %cl 176; X64-NEXT: movl $248, %eax 177; X64-NEXT: cmovgel %ecx, %eax 178; X64-NEXT: movsbl %al, %eax 179; X64-NEXT: retq 180 %a = mul i4 %y, %z 181 %tmp = call i4 @llvm.sadd.sat.i4(i4 %x, i4 %a) 182 ret i4 %tmp 183} 184