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.ssub.sat.i4(i4, i4) 6declare i8 @llvm.ssub.sat.i8(i8, i8) 7declare i16 @llvm.ssub.sat.i16(i16, i16) 8declare i32 @llvm.ssub.sat.i32(i32, i32) 9declare i64 @llvm.ssub.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: movl {{[0-9]+}}(%esp), %edx 16; X86-NEXT: imull {{[0-9]+}}(%esp), %edx 17; X86-NEXT: xorl %ecx, %ecx 18; X86-NEXT: cmpl %edx, %eax 19; X86-NEXT: setns %cl 20; X86-NEXT: addl $2147483647, %ecx # imm = 0x7FFFFFFF 21; X86-NEXT: subl %edx, %eax 22; X86-NEXT: cmovol %ecx, %eax 23; X86-NEXT: retl 24; 25; X64-LABEL: func32: 26; X64: # %bb.0: 27; X64-NEXT: imull %edx, %esi 28; X64-NEXT: xorl %eax, %eax 29; X64-NEXT: cmpl %esi, %edi 30; X64-NEXT: setns %al 31; X64-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF 32; X64-NEXT: subl %esi, %edi 33; X64-NEXT: cmovnol %edi, %eax 34; X64-NEXT: retq 35 %a = mul i32 %y, %z 36 %tmp = call i32 @llvm.ssub.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: subl {{[0-9]+}}(%esp), %eax 47; X86-NEXT: sbbl {{[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: xorl %ecx, %ecx 62; X64-NEXT: cmpq %rdx, %rdi 63; X64-NEXT: setns %cl 64; X64-NEXT: movabsq $9223372036854775807, %rax # imm = 0x7FFFFFFFFFFFFFFF 65; X64-NEXT: addq %rcx, %rax 66; X64-NEXT: subq %rdx, %rdi 67; X64-NEXT: cmovnoq %rdi, %rax 68; X64-NEXT: retq 69 %a = mul i64 %y, %z 70 %tmp = call i64 @llvm.ssub.sat.i64(i64 %x, i64 %z) 71 ret i64 %tmp 72} 73 74define signext i16 @func16(i16 signext %x, i16 signext %y, i16 signext %z) nounwind { 75; X86-LABEL: func16: 76; X86: # %bb.0: 77; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 78; X86-NEXT: movzwl {{[0-9]+}}(%esp), %edx 79; X86-NEXT: imulw {{[0-9]+}}(%esp), %dx 80; X86-NEXT: xorl %ecx, %ecx 81; X86-NEXT: cmpw %dx, %ax 82; X86-NEXT: setns %cl 83; X86-NEXT: addl $32767, %ecx # imm = 0x7FFF 84; X86-NEXT: subw %dx, %ax 85; X86-NEXT: cmovol %ecx, %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: imull %edx, %esi 92; X64-NEXT: xorl %eax, %eax 93; X64-NEXT: cmpw %si, %di 94; X64-NEXT: setns %al 95; X64-NEXT: addl $32767, %eax # imm = 0x7FFF 96; X64-NEXT: subw %si, %di 97; X64-NEXT: cmovnol %edi, %eax 98; X64-NEXT: # kill: def $ax killed $ax killed $eax 99; X64-NEXT: retq 100 %a = mul i16 %y, %z 101 %tmp = call i16 @llvm.ssub.sat.i16(i16 %x, i16 %a) 102 ret i16 %tmp 103} 104 105define signext i8 @func8(i8 signext %x, i8 signext %y, i8 signext %z) nounwind { 106; X86-LABEL: func8: 107; X86: # %bb.0: 108; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx 109; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 110; X86-NEXT: mulb {{[0-9]+}}(%esp) 111; X86-NEXT: xorl %ecx, %ecx 112; X86-NEXT: cmpb %al, %dl 113; X86-NEXT: setns %cl 114; X86-NEXT: addl $127, %ecx 115; X86-NEXT: subb %al, %dl 116; X86-NEXT: movzbl %dl, %eax 117; X86-NEXT: cmovol %ecx, %eax 118; X86-NEXT: # kill: def $al killed $al killed $eax 119; X86-NEXT: retl 120; 121; X64-LABEL: func8: 122; X64: # %bb.0: 123; X64-NEXT: movl %esi, %eax 124; X64-NEXT: # kill: def $al killed $al killed $eax 125; X64-NEXT: mulb %dl 126; X64-NEXT: xorl %ecx, %ecx 127; X64-NEXT: cmpb %al, %dil 128; X64-NEXT: setns %cl 129; X64-NEXT: addl $127, %ecx 130; X64-NEXT: subb %al, %dil 131; X64-NEXT: movzbl %dil, %eax 132; X64-NEXT: cmovol %ecx, %eax 133; X64-NEXT: # kill: def $al killed $al killed $eax 134; X64-NEXT: retq 135 %a = mul i8 %y, %z 136 %tmp = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %a) 137 ret i8 %tmp 138} 139 140define signext i4 @func4(i4 signext %x, i4 signext %y, i4 signext %z) nounwind { 141; X86-LABEL: func4: 142; X86: # %bb.0: 143; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 144; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 145; X86-NEXT: mulb {{[0-9]+}}(%esp) 146; X86-NEXT: shlb $4, %al 147; X86-NEXT: sarb $4, %al 148; X86-NEXT: subb %al, %cl 149; X86-NEXT: movzbl %cl, %eax 150; X86-NEXT: cmpb $7, %cl 151; X86-NEXT: movl $7, %ecx 152; X86-NEXT: cmovll %eax, %ecx 153; X86-NEXT: cmpb $-7, %cl 154; X86-NEXT: movl $248, %eax 155; X86-NEXT: cmovgel %ecx, %eax 156; X86-NEXT: movsbl %al, %eax 157; X86-NEXT: retl 158; 159; X64-LABEL: func4: 160; X64: # %bb.0: 161; X64-NEXT: movl %esi, %eax 162; X64-NEXT: # kill: def $al killed $al killed $eax 163; X64-NEXT: mulb %dl 164; X64-NEXT: shlb $4, %al 165; X64-NEXT: sarb $4, %al 166; X64-NEXT: subb %al, %dil 167; X64-NEXT: movzbl %dil, %eax 168; X64-NEXT: cmpb $7, %al 169; X64-NEXT: movl $7, %ecx 170; X64-NEXT: cmovll %eax, %ecx 171; X64-NEXT: cmpb $-7, %cl 172; X64-NEXT: movl $248, %eax 173; X64-NEXT: cmovgel %ecx, %eax 174; X64-NEXT: movsbl %al, %eax 175; X64-NEXT: retq 176 %a = mul i4 %y, %z 177 %tmp = call i4 @llvm.ssub.sat.i4(i4 %x, i4 %a) 178 ret i4 %tmp 179} 180