1382 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefixes=X644 5;6; trunc(abs(sub(sext(a),sext(b)))) -> abds(a,b)7;8 9define i8 @abd_ext_i8(i8 %a, i8 %b) nounwind {10; X86-LABEL: abd_ext_i8:11; X86: # %bb.0:12; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax13; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx14; X86-NEXT: movl %ecx, %edx15; X86-NEXT: subl %eax, %edx16; X86-NEXT: subl %ecx, %eax17; X86-NEXT: cmovll %edx, %eax18; X86-NEXT: # kill: def $al killed $al killed $eax19; X86-NEXT: retl20;21; X64-LABEL: abd_ext_i8:22; X64: # %bb.0:23; X64-NEXT: movsbl %sil, %eax24; X64-NEXT: movsbl %dil, %ecx25; X64-NEXT: movl %ecx, %edx26; X64-NEXT: subl %eax, %edx27; X64-NEXT: subl %ecx, %eax28; X64-NEXT: cmovll %edx, %eax29; X64-NEXT: # kill: def $al killed $al killed $eax30; X64-NEXT: retq31 %aext = sext i8 %a to i6432 %bext = sext i8 %b to i6433 %sub = sub i64 %aext, %bext34 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)35 %trunc = trunc i64 %abs to i836 ret i8 %trunc37}38 39define i8 @abd_ext_i8_i16(i8 %a, i16 %b) nounwind {40; X86-LABEL: abd_ext_i8_i16:41; X86: # %bb.0:42; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax43; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx44; X86-NEXT: movl %ecx, %edx45; X86-NEXT: subl %eax, %edx46; X86-NEXT: subl %ecx, %eax47; X86-NEXT: cmovll %edx, %eax48; X86-NEXT: # kill: def $al killed $al killed $eax49; X86-NEXT: retl50;51; X64-LABEL: abd_ext_i8_i16:52; X64: # %bb.0:53; X64-NEXT: movsbl %dil, %ecx54; X64-NEXT: subl %esi, %edi55; X64-NEXT: movswl %si, %eax56; X64-NEXT: subl %ecx, %eax57; X64-NEXT: cmovll %edi, %eax58; X64-NEXT: # kill: def $al killed $al killed $eax59; X64-NEXT: retq60 %aext = sext i8 %a to i6461 %bext = sext i16 %b to i6462 %sub = sub i64 %aext, %bext63 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)64 %trunc = trunc i64 %abs to i865 ret i8 %trunc66}67 68define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind {69; X86-LABEL: abd_ext_i8_undef:70; X86: # %bb.0:71; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax72; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx73; X86-NEXT: movl %ecx, %edx74; X86-NEXT: subl %eax, %edx75; X86-NEXT: subl %ecx, %eax76; X86-NEXT: cmovll %edx, %eax77; X86-NEXT: # kill: def $al killed $al killed $eax78; X86-NEXT: retl79;80; X64-LABEL: abd_ext_i8_undef:81; X64: # %bb.0:82; X64-NEXT: movsbl %sil, %eax83; X64-NEXT: movsbl %dil, %ecx84; X64-NEXT: movl %ecx, %edx85; X64-NEXT: subl %eax, %edx86; X64-NEXT: subl %ecx, %eax87; X64-NEXT: cmovll %edx, %eax88; X64-NEXT: # kill: def $al killed $al killed $eax89; X64-NEXT: retq90 %aext = sext i8 %a to i6491 %bext = sext i8 %b to i6492 %sub = sub i64 %aext, %bext93 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)94 %trunc = trunc i64 %abs to i895 ret i8 %trunc96}97 98define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind {99; X86-LABEL: abd_ext_i16:100; X86: # %bb.0:101; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax102; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx103; X86-NEXT: movl %ecx, %edx104; X86-NEXT: subl %eax, %edx105; X86-NEXT: subl %ecx, %eax106; X86-NEXT: cmovll %edx, %eax107; X86-NEXT: # kill: def $ax killed $ax killed $eax108; X86-NEXT: retl109;110; X64-LABEL: abd_ext_i16:111; X64: # %bb.0:112; X64-NEXT: movswl %si, %eax113; X64-NEXT: movswl %di, %ecx114; X64-NEXT: movl %ecx, %edx115; X64-NEXT: subl %eax, %edx116; X64-NEXT: subl %ecx, %eax117; X64-NEXT: cmovll %edx, %eax118; X64-NEXT: # kill: def $ax killed $ax killed $eax119; X64-NEXT: retq120 %aext = sext i16 %a to i64121 %bext = sext i16 %b to i64122 %sub = sub i64 %aext, %bext123 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)124 %trunc = trunc i64 %abs to i16125 ret i16 %trunc126}127 128define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind {129; X86-LABEL: abd_ext_i16_i32:130; X86: # %bb.0:131; X86-NEXT: movl {{[0-9]+}}(%esp), %eax132; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx133; X86-NEXT: movl %ecx, %edx134; X86-NEXT: subl %eax, %edx135; X86-NEXT: subl %ecx, %eax136; X86-NEXT: cmovll %edx, %eax137; X86-NEXT: # kill: def $ax killed $ax killed $eax138; X86-NEXT: retl139;140; X64-LABEL: abd_ext_i16_i32:141; X64: # %bb.0:142; X64-NEXT: movswl %di, %ecx143; X64-NEXT: movl %edi, %eax144; X64-NEXT: subl %esi, %eax145; X64-NEXT: subl %ecx, %esi146; X64-NEXT: cmovgel %esi, %eax147; X64-NEXT: # kill: def $ax killed $ax killed $eax148; X64-NEXT: retq149 %aext = sext i16 %a to i64150 %bext = sext i32 %b to i64151 %sub = sub i64 %aext, %bext152 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)153 %trunc = trunc i64 %abs to i16154 ret i16 %trunc155}156 157define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind {158; X86-LABEL: abd_ext_i16_undef:159; X86: # %bb.0:160; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax161; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx162; X86-NEXT: movl %ecx, %edx163; X86-NEXT: subl %eax, %edx164; X86-NEXT: subl %ecx, %eax165; X86-NEXT: cmovll %edx, %eax166; X86-NEXT: # kill: def $ax killed $ax killed $eax167; X86-NEXT: retl168;169; X64-LABEL: abd_ext_i16_undef:170; X64: # %bb.0:171; X64-NEXT: movswl %si, %eax172; X64-NEXT: movswl %di, %ecx173; X64-NEXT: movl %ecx, %edx174; X64-NEXT: subl %eax, %edx175; X64-NEXT: subl %ecx, %eax176; X64-NEXT: cmovll %edx, %eax177; X64-NEXT: # kill: def $ax killed $ax killed $eax178; X64-NEXT: retq179 %aext = sext i16 %a to i64180 %bext = sext i16 %b to i64181 %sub = sub i64 %aext, %bext182 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)183 %trunc = trunc i64 %abs to i16184 ret i16 %trunc185}186 187define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind {188; X86-LABEL: abd_ext_i32:189; X86: # %bb.0:190; X86-NEXT: movl {{[0-9]+}}(%esp), %eax191; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx192; X86-NEXT: movl %ecx, %edx193; X86-NEXT: subl %eax, %edx194; X86-NEXT: subl %ecx, %eax195; X86-NEXT: cmovll %edx, %eax196; X86-NEXT: retl197;198; X64-LABEL: abd_ext_i32:199; X64: # %bb.0:200; X64-NEXT: movl %edi, %eax201; X64-NEXT: subl %esi, %eax202; X64-NEXT: subl %edi, %esi203; X64-NEXT: cmovgel %esi, %eax204; X64-NEXT: retq205 %aext = sext i32 %a to i64206 %bext = sext i32 %b to i64207 %sub = sub i64 %aext, %bext208 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)209 %trunc = trunc i64 %abs to i32210 ret i32 %trunc211}212 213define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind {214; X86-LABEL: abd_ext_i32_i16:215; X86: # %bb.0:216; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax217; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx218; X86-NEXT: movl %ecx, %edx219; X86-NEXT: subl %eax, %edx220; X86-NEXT: subl %ecx, %eax221; X86-NEXT: cmovll %edx, %eax222; X86-NEXT: retl223;224; X64-LABEL: abd_ext_i32_i16:225; X64: # %bb.0:226; X64-NEXT: movswl %si, %eax227; X64-NEXT: movl %edi, %ecx228; X64-NEXT: subl %eax, %ecx229; X64-NEXT: subl %edi, %eax230; X64-NEXT: cmovll %ecx, %eax231; X64-NEXT: retq232 %aext = sext i32 %a to i64233 %bext = sext i16 %b to i64234 %sub = sub i64 %aext, %bext235 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)236 %trunc = trunc i64 %abs to i32237 ret i32 %trunc238}239 240define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind {241; X86-LABEL: abd_ext_i32_undef:242; X86: # %bb.0:243; X86-NEXT: movl {{[0-9]+}}(%esp), %eax244; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx245; X86-NEXT: movl %ecx, %edx246; X86-NEXT: subl %eax, %edx247; X86-NEXT: subl %ecx, %eax248; X86-NEXT: cmovll %edx, %eax249; X86-NEXT: retl250;251; X64-LABEL: abd_ext_i32_undef:252; X64: # %bb.0:253; X64-NEXT: movl %edi, %eax254; X64-NEXT: subl %esi, %eax255; X64-NEXT: subl %edi, %esi256; X64-NEXT: cmovgel %esi, %eax257; X64-NEXT: retq258 %aext = sext i32 %a to i64259 %bext = sext i32 %b to i64260 %sub = sub i64 %aext, %bext261 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)262 %trunc = trunc i64 %abs to i32263 ret i32 %trunc264}265 266define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind {267; X86-LABEL: abd_ext_i64:268; X86: # %bb.0:269; X86-NEXT: pushl %ebx270; X86-NEXT: pushl %edi271; X86-NEXT: pushl %esi272; X86-NEXT: movl {{[0-9]+}}(%esp), %eax273; X86-NEXT: movl {{[0-9]+}}(%esp), %edx274; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx275; X86-NEXT: movl {{[0-9]+}}(%esp), %esi276; X86-NEXT: movl %ecx, %edi277; X86-NEXT: subl %eax, %edi278; X86-NEXT: movl %esi, %ebx279; X86-NEXT: sbbl %edx, %ebx280; X86-NEXT: subl %ecx, %eax281; X86-NEXT: sbbl %esi, %edx282; X86-NEXT: cmovll %edi, %eax283; X86-NEXT: cmovll %ebx, %edx284; X86-NEXT: popl %esi285; X86-NEXT: popl %edi286; X86-NEXT: popl %ebx287; X86-NEXT: retl288;289; X64-LABEL: abd_ext_i64:290; X64: # %bb.0:291; X64-NEXT: movq %rdi, %rax292; X64-NEXT: subq %rsi, %rax293; X64-NEXT: subq %rdi, %rsi294; X64-NEXT: cmovgeq %rsi, %rax295; X64-NEXT: retq296 %aext = sext i64 %a to i128297 %bext = sext i64 %b to i128298 %sub = sub i128 %aext, %bext299 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)300 %trunc = trunc i128 %abs to i64301 ret i64 %trunc302}303 304define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {305; X86-LABEL: abd_ext_i64_undef:306; X86: # %bb.0:307; X86-NEXT: pushl %ebx308; X86-NEXT: pushl %edi309; X86-NEXT: pushl %esi310; X86-NEXT: movl {{[0-9]+}}(%esp), %eax311; X86-NEXT: movl {{[0-9]+}}(%esp), %edx312; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx313; X86-NEXT: movl {{[0-9]+}}(%esp), %esi314; X86-NEXT: movl %ecx, %edi315; X86-NEXT: subl %eax, %edi316; X86-NEXT: movl %esi, %ebx317; X86-NEXT: sbbl %edx, %ebx318; X86-NEXT: subl %ecx, %eax319; X86-NEXT: sbbl %esi, %edx320; X86-NEXT: cmovll %edi, %eax321; X86-NEXT: cmovll %ebx, %edx322; X86-NEXT: popl %esi323; X86-NEXT: popl %edi324; X86-NEXT: popl %ebx325; X86-NEXT: retl326;327; X64-LABEL: abd_ext_i64_undef:328; X64: # %bb.0:329; X64-NEXT: movq %rdi, %rax330; X64-NEXT: subq %rsi, %rax331; X64-NEXT: subq %rdi, %rsi332; X64-NEXT: cmovgeq %rsi, %rax333; X64-NEXT: retq334 %aext = sext i64 %a to i128335 %bext = sext i64 %b to i128336 %sub = sub i128 %aext, %bext337 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)338 %trunc = trunc i128 %abs to i64339 ret i64 %trunc340}341 342define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {343; X86-LABEL: abd_ext_i128:344; X86: # %bb.0:345; X86-NEXT: pushl %ebp346; X86-NEXT: movl %esp, %ebp347; X86-NEXT: pushl %ebx348; X86-NEXT: pushl %edi349; X86-NEXT: pushl %esi350; X86-NEXT: andl $-16, %esp351; X86-NEXT: subl $16, %esp352; X86-NEXT: movl 40(%ebp), %ecx353; X86-NEXT: movl 44(%ebp), %edx354; X86-NEXT: movl 24(%ebp), %eax355; X86-NEXT: movl 28(%ebp), %esi356; X86-NEXT: subl %ecx, %eax357; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill358; X86-NEXT: movl %esi, %eax359; X86-NEXT: sbbl %edx, %eax360; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill361; X86-NEXT: movl 48(%ebp), %esi362; X86-NEXT: movl 32(%ebp), %edi363; X86-NEXT: sbbl %esi, %edi364; X86-NEXT: movl 52(%ebp), %ebx365; X86-NEXT: movl 36(%ebp), %eax366; X86-NEXT: sbbl %ebx, %eax367; X86-NEXT: subl 24(%ebp), %ecx368; X86-NEXT: sbbl 28(%ebp), %edx369; X86-NEXT: sbbl 32(%ebp), %esi370; X86-NEXT: sbbl 36(%ebp), %ebx371; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload372; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload373; X86-NEXT: cmovll %edi, %esi374; X86-NEXT: cmovll %eax, %ebx375; X86-NEXT: movl 8(%ebp), %eax376; X86-NEXT: movl %ebx, 12(%eax)377; X86-NEXT: movl %esi, 8(%eax)378; X86-NEXT: movl %edx, 4(%eax)379; X86-NEXT: movl %ecx, (%eax)380; X86-NEXT: leal -12(%ebp), %esp381; X86-NEXT: popl %esi382; X86-NEXT: popl %edi383; X86-NEXT: popl %ebx384; X86-NEXT: popl %ebp385; X86-NEXT: retl $4386;387; X64-LABEL: abd_ext_i128:388; X64: # %bb.0:389; X64-NEXT: movq %rdi, %rax390; X64-NEXT: subq %rdx, %rax391; X64-NEXT: movq %rsi, %r8392; X64-NEXT: sbbq %rcx, %r8393; X64-NEXT: subq %rdi, %rdx394; X64-NEXT: sbbq %rsi, %rcx395; X64-NEXT: cmovgeq %rdx, %rax396; X64-NEXT: cmovgeq %rcx, %r8397; X64-NEXT: movq %r8, %rdx398; X64-NEXT: retq399 %aext = sext i128 %a to i256400 %bext = sext i128 %b to i256401 %sub = sub i256 %aext, %bext402 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)403 %trunc = trunc i256 %abs to i128404 ret i128 %trunc405}406 407define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {408; X86-LABEL: abd_ext_i128_undef:409; X86: # %bb.0:410; X86-NEXT: pushl %ebp411; X86-NEXT: movl %esp, %ebp412; X86-NEXT: pushl %ebx413; X86-NEXT: pushl %edi414; X86-NEXT: pushl %esi415; X86-NEXT: andl $-16, %esp416; X86-NEXT: subl $16, %esp417; X86-NEXT: movl 40(%ebp), %ecx418; X86-NEXT: movl 44(%ebp), %edx419; X86-NEXT: movl 24(%ebp), %eax420; X86-NEXT: movl 28(%ebp), %esi421; X86-NEXT: subl %ecx, %eax422; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill423; X86-NEXT: movl %esi, %eax424; X86-NEXT: sbbl %edx, %eax425; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill426; X86-NEXT: movl 48(%ebp), %esi427; X86-NEXT: movl 32(%ebp), %edi428; X86-NEXT: sbbl %esi, %edi429; X86-NEXT: movl 52(%ebp), %ebx430; X86-NEXT: movl 36(%ebp), %eax431; X86-NEXT: sbbl %ebx, %eax432; X86-NEXT: subl 24(%ebp), %ecx433; X86-NEXT: sbbl 28(%ebp), %edx434; X86-NEXT: sbbl 32(%ebp), %esi435; X86-NEXT: sbbl 36(%ebp), %ebx436; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload437; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload438; X86-NEXT: cmovll %edi, %esi439; X86-NEXT: cmovll %eax, %ebx440; X86-NEXT: movl 8(%ebp), %eax441; X86-NEXT: movl %ebx, 12(%eax)442; X86-NEXT: movl %esi, 8(%eax)443; X86-NEXT: movl %edx, 4(%eax)444; X86-NEXT: movl %ecx, (%eax)445; X86-NEXT: leal -12(%ebp), %esp446; X86-NEXT: popl %esi447; X86-NEXT: popl %edi448; X86-NEXT: popl %ebx449; X86-NEXT: popl %ebp450; X86-NEXT: retl $4451;452; X64-LABEL: abd_ext_i128_undef:453; X64: # %bb.0:454; X64-NEXT: movq %rdi, %rax455; X64-NEXT: subq %rdx, %rax456; X64-NEXT: movq %rsi, %r8457; X64-NEXT: sbbq %rcx, %r8458; X64-NEXT: subq %rdi, %rdx459; X64-NEXT: sbbq %rsi, %rcx460; X64-NEXT: cmovgeq %rdx, %rax461; X64-NEXT: cmovgeq %rcx, %r8462; X64-NEXT: movq %r8, %rdx463; X64-NEXT: retq464 %aext = sext i128 %a to i256465 %bext = sext i128 %b to i256466 %sub = sub i256 %aext, %bext467 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)468 %trunc = trunc i256 %abs to i128469 ret i128 %trunc470}471 472;473; sub(smax(a,b),smin(a,b)) -> abds(a,b)474;475 476define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {477; X86-LABEL: abd_minmax_i8:478; X86: # %bb.0:479; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax480; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx481; X86-NEXT: movl %ecx, %edx482; X86-NEXT: subl %eax, %edx483; X86-NEXT: subl %ecx, %eax484; X86-NEXT: cmovll %edx, %eax485; X86-NEXT: # kill: def $al killed $al killed $eax486; X86-NEXT: retl487;488; X64-LABEL: abd_minmax_i8:489; X64: # %bb.0:490; X64-NEXT: movsbl %sil, %eax491; X64-NEXT: movsbl %dil, %ecx492; X64-NEXT: movl %ecx, %edx493; X64-NEXT: subl %eax, %edx494; X64-NEXT: subl %ecx, %eax495; X64-NEXT: cmovll %edx, %eax496; X64-NEXT: # kill: def $al killed $al killed $eax497; X64-NEXT: retq498 %min = call i8 @llvm.smin.i8(i8 %a, i8 %b)499 %max = call i8 @llvm.smax.i8(i8 %a, i8 %b)500 %sub = sub i8 %max, %min501 ret i8 %sub502}503 504define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {505; X86-LABEL: abd_minmax_i16:506; X86: # %bb.0:507; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax508; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx509; X86-NEXT: movl %ecx, %edx510; X86-NEXT: subl %eax, %edx511; X86-NEXT: subl %ecx, %eax512; X86-NEXT: cmovll %edx, %eax513; X86-NEXT: # kill: def $ax killed $ax killed $eax514; X86-NEXT: retl515;516; X64-LABEL: abd_minmax_i16:517; X64: # %bb.0:518; X64-NEXT: movswl %si, %eax519; X64-NEXT: movswl %di, %ecx520; X64-NEXT: movl %ecx, %edx521; X64-NEXT: subl %eax, %edx522; X64-NEXT: subl %ecx, %eax523; X64-NEXT: cmovll %edx, %eax524; X64-NEXT: # kill: def $ax killed $ax killed $eax525; X64-NEXT: retq526 %min = call i16 @llvm.smin.i16(i16 %a, i16 %b)527 %max = call i16 @llvm.smax.i16(i16 %a, i16 %b)528 %sub = sub i16 %max, %min529 ret i16 %sub530}531 532define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {533; X86-LABEL: abd_minmax_i32:534; X86: # %bb.0:535; X86-NEXT: movl {{[0-9]+}}(%esp), %eax536; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx537; X86-NEXT: movl %ecx, %edx538; X86-NEXT: subl %eax, %edx539; X86-NEXT: subl %ecx, %eax540; X86-NEXT: cmovll %edx, %eax541; X86-NEXT: retl542;543; X64-LABEL: abd_minmax_i32:544; X64: # %bb.0:545; X64-NEXT: movl %edi, %eax546; X64-NEXT: subl %esi, %eax547; X64-NEXT: subl %edi, %esi548; X64-NEXT: cmovgel %esi, %eax549; X64-NEXT: retq550 %min = call i32 @llvm.smin.i32(i32 %a, i32 %b)551 %max = call i32 @llvm.smax.i32(i32 %a, i32 %b)552 %sub = sub i32 %max, %min553 ret i32 %sub554}555 556define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {557; X86-LABEL: abd_minmax_i64:558; X86: # %bb.0:559; X86-NEXT: pushl %ebx560; X86-NEXT: pushl %edi561; X86-NEXT: pushl %esi562; X86-NEXT: movl {{[0-9]+}}(%esp), %eax563; X86-NEXT: movl {{[0-9]+}}(%esp), %edx564; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx565; X86-NEXT: movl {{[0-9]+}}(%esp), %esi566; X86-NEXT: movl %ecx, %edi567; X86-NEXT: subl %eax, %edi568; X86-NEXT: movl %esi, %ebx569; X86-NEXT: sbbl %edx, %ebx570; X86-NEXT: subl %ecx, %eax571; X86-NEXT: sbbl %esi, %edx572; X86-NEXT: cmovll %edi, %eax573; X86-NEXT: cmovll %ebx, %edx574; X86-NEXT: popl %esi575; X86-NEXT: popl %edi576; X86-NEXT: popl %ebx577; X86-NEXT: retl578;579; X64-LABEL: abd_minmax_i64:580; X64: # %bb.0:581; X64-NEXT: movq %rdi, %rax582; X64-NEXT: subq %rsi, %rax583; X64-NEXT: subq %rdi, %rsi584; X64-NEXT: cmovgeq %rsi, %rax585; X64-NEXT: retq586 %min = call i64 @llvm.smin.i64(i64 %a, i64 %b)587 %max = call i64 @llvm.smax.i64(i64 %a, i64 %b)588 %sub = sub i64 %max, %min589 ret i64 %sub590}591 592define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {593; X86-LABEL: abd_minmax_i128:594; X86: # %bb.0:595; X86-NEXT: pushl %ebp596; X86-NEXT: movl %esp, %ebp597; X86-NEXT: pushl %ebx598; X86-NEXT: pushl %edi599; X86-NEXT: pushl %esi600; X86-NEXT: andl $-16, %esp601; X86-NEXT: subl $16, %esp602; X86-NEXT: movl 40(%ebp), %ecx603; X86-NEXT: movl 44(%ebp), %edx604; X86-NEXT: movl 24(%ebp), %eax605; X86-NEXT: movl 28(%ebp), %esi606; X86-NEXT: subl %ecx, %eax607; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill608; X86-NEXT: movl %esi, %eax609; X86-NEXT: sbbl %edx, %eax610; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill611; X86-NEXT: movl 48(%ebp), %esi612; X86-NEXT: movl 32(%ebp), %edi613; X86-NEXT: sbbl %esi, %edi614; X86-NEXT: movl 52(%ebp), %ebx615; X86-NEXT: movl 36(%ebp), %eax616; X86-NEXT: sbbl %ebx, %eax617; X86-NEXT: subl 24(%ebp), %ecx618; X86-NEXT: sbbl 28(%ebp), %edx619; X86-NEXT: sbbl 32(%ebp), %esi620; X86-NEXT: sbbl 36(%ebp), %ebx621; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload622; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload623; X86-NEXT: cmovll %edi, %esi624; X86-NEXT: cmovll %eax, %ebx625; X86-NEXT: movl 8(%ebp), %eax626; X86-NEXT: movl %ebx, 12(%eax)627; X86-NEXT: movl %esi, 8(%eax)628; X86-NEXT: movl %edx, 4(%eax)629; X86-NEXT: movl %ecx, (%eax)630; X86-NEXT: leal -12(%ebp), %esp631; X86-NEXT: popl %esi632; X86-NEXT: popl %edi633; X86-NEXT: popl %ebx634; X86-NEXT: popl %ebp635; X86-NEXT: retl $4636;637; X64-LABEL: abd_minmax_i128:638; X64: # %bb.0:639; X64-NEXT: movq %rdi, %rax640; X64-NEXT: subq %rdx, %rax641; X64-NEXT: movq %rsi, %r8642; X64-NEXT: sbbq %rcx, %r8643; X64-NEXT: subq %rdi, %rdx644; X64-NEXT: sbbq %rsi, %rcx645; X64-NEXT: cmovgeq %rdx, %rax646; X64-NEXT: cmovgeq %rcx, %r8647; X64-NEXT: movq %r8, %rdx648; X64-NEXT: retq649 %min = call i128 @llvm.smin.i128(i128 %a, i128 %b)650 %max = call i128 @llvm.smax.i128(i128 %a, i128 %b)651 %sub = sub i128 %max, %min652 ret i128 %sub653}654 655;656; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b)657;658 659define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {660; X86-LABEL: abd_cmp_i8:661; X86: # %bb.0:662; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax663; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx664; X86-NEXT: movl %ecx, %edx665; X86-NEXT: subl %eax, %edx666; X86-NEXT: subl %ecx, %eax667; X86-NEXT: cmovll %edx, %eax668; X86-NEXT: # kill: def $al killed $al killed $eax669; X86-NEXT: retl670;671; X64-LABEL: abd_cmp_i8:672; X64: # %bb.0:673; X64-NEXT: movsbl %sil, %eax674; X64-NEXT: movsbl %dil, %ecx675; X64-NEXT: movl %ecx, %edx676; X64-NEXT: subl %eax, %edx677; X64-NEXT: subl %ecx, %eax678; X64-NEXT: cmovll %edx, %eax679; X64-NEXT: # kill: def $al killed $al killed $eax680; X64-NEXT: retq681 %cmp = icmp sgt i8 %a, %b682 %ab = sub i8 %a, %b683 %ba = sub i8 %b, %a684 %sel = select i1 %cmp, i8 %ab, i8 %ba685 ret i8 %sel686}687 688define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {689; X86-LABEL: abd_cmp_i16:690; X86: # %bb.0:691; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax692; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx693; X86-NEXT: movl %ecx, %edx694; X86-NEXT: subl %eax, %edx695; X86-NEXT: subl %ecx, %eax696; X86-NEXT: cmovll %edx, %eax697; X86-NEXT: # kill: def $ax killed $ax killed $eax698; X86-NEXT: retl699;700; X64-LABEL: abd_cmp_i16:701; X64: # %bb.0:702; X64-NEXT: movswl %si, %eax703; X64-NEXT: movswl %di, %ecx704; X64-NEXT: movl %ecx, %edx705; X64-NEXT: subl %eax, %edx706; X64-NEXT: subl %ecx, %eax707; X64-NEXT: cmovll %edx, %eax708; X64-NEXT: # kill: def $ax killed $ax killed $eax709; X64-NEXT: retq710 %cmp = icmp sge i16 %a, %b711 %ab = sub i16 %a, %b712 %ba = sub i16 %b, %a713 %sel = select i1 %cmp, i16 %ab, i16 %ba714 ret i16 %sel715}716 717define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {718; X86-LABEL: abd_cmp_i32:719; X86: # %bb.0:720; X86-NEXT: movl {{[0-9]+}}(%esp), %eax721; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx722; X86-NEXT: movl %ecx, %edx723; X86-NEXT: subl %eax, %edx724; X86-NEXT: subl %ecx, %eax725; X86-NEXT: cmovll %edx, %eax726; X86-NEXT: retl727;728; X64-LABEL: abd_cmp_i32:729; X64: # %bb.0:730; X64-NEXT: movl %edi, %eax731; X64-NEXT: subl %esi, %eax732; X64-NEXT: subl %edi, %esi733; X64-NEXT: cmovgel %esi, %eax734; X64-NEXT: retq735 %cmp = icmp slt i32 %a, %b736 %ab = sub i32 %a, %b737 %ba = sub i32 %b, %a738 %sel = select i1 %cmp, i32 %ba, i32 %ab739 ret i32 %sel740}741 742define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {743; X86-LABEL: abd_cmp_i64:744; X86: # %bb.0:745; X86-NEXT: pushl %ebx746; X86-NEXT: pushl %edi747; X86-NEXT: pushl %esi748; X86-NEXT: movl {{[0-9]+}}(%esp), %eax749; X86-NEXT: movl {{[0-9]+}}(%esp), %edx750; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx751; X86-NEXT: movl {{[0-9]+}}(%esp), %esi752; X86-NEXT: movl %ecx, %edi753; X86-NEXT: subl %eax, %edi754; X86-NEXT: movl %esi, %ebx755; X86-NEXT: sbbl %edx, %ebx756; X86-NEXT: subl %ecx, %eax757; X86-NEXT: sbbl %esi, %edx758; X86-NEXT: cmovll %edi, %eax759; X86-NEXT: cmovll %ebx, %edx760; X86-NEXT: popl %esi761; X86-NEXT: popl %edi762; X86-NEXT: popl %ebx763; X86-NEXT: retl764;765; X64-LABEL: abd_cmp_i64:766; X64: # %bb.0:767; X64-NEXT: movq %rdi, %rax768; X64-NEXT: subq %rsi, %rax769; X64-NEXT: subq %rdi, %rsi770; X64-NEXT: cmovgeq %rsi, %rax771; X64-NEXT: retq772 %cmp = icmp sge i64 %a, %b773 %ab = sub i64 %a, %b774 %ba = sub i64 %b, %a775 %sel = select i1 %cmp, i64 %ab, i64 %ba776 ret i64 %sel777}778 779define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {780; X86-LABEL: abd_cmp_i128:781; X86: # %bb.0:782; X86-NEXT: pushl %ebp783; X86-NEXT: movl %esp, %ebp784; X86-NEXT: pushl %ebx785; X86-NEXT: pushl %edi786; X86-NEXT: pushl %esi787; X86-NEXT: andl $-16, %esp788; X86-NEXT: subl $16, %esp789; X86-NEXT: movl 40(%ebp), %ecx790; X86-NEXT: movl 44(%ebp), %edx791; X86-NEXT: movl 24(%ebp), %eax792; X86-NEXT: movl 28(%ebp), %esi793; X86-NEXT: subl %ecx, %eax794; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill795; X86-NEXT: movl %esi, %eax796; X86-NEXT: sbbl %edx, %eax797; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill798; X86-NEXT: movl 48(%ebp), %esi799; X86-NEXT: movl 32(%ebp), %edi800; X86-NEXT: sbbl %esi, %edi801; X86-NEXT: movl 52(%ebp), %ebx802; X86-NEXT: movl 36(%ebp), %eax803; X86-NEXT: sbbl %ebx, %eax804; X86-NEXT: subl 24(%ebp), %ecx805; X86-NEXT: sbbl 28(%ebp), %edx806; X86-NEXT: sbbl 32(%ebp), %esi807; X86-NEXT: sbbl 36(%ebp), %ebx808; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload809; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload810; X86-NEXT: cmovll %edi, %esi811; X86-NEXT: cmovll %eax, %ebx812; X86-NEXT: movl 8(%ebp), %eax813; X86-NEXT: movl %ebx, 12(%eax)814; X86-NEXT: movl %esi, 8(%eax)815; X86-NEXT: movl %edx, 4(%eax)816; X86-NEXT: movl %ecx, (%eax)817; X86-NEXT: leal -12(%ebp), %esp818; X86-NEXT: popl %esi819; X86-NEXT: popl %edi820; X86-NEXT: popl %ebx821; X86-NEXT: popl %ebp822; X86-NEXT: retl $4823;824; X64-LABEL: abd_cmp_i128:825; X64: # %bb.0:826; X64-NEXT: movq %rdi, %rax827; X64-NEXT: subq %rdx, %rax828; X64-NEXT: movq %rsi, %r8829; X64-NEXT: sbbq %rcx, %r8830; X64-NEXT: subq %rdi, %rdx831; X64-NEXT: sbbq %rsi, %rcx832; X64-NEXT: cmovgeq %rdx, %rax833; X64-NEXT: cmovgeq %rcx, %r8834; X64-NEXT: movq %r8, %rdx835; X64-NEXT: retq836 %cmp = icmp sge i128 %a, %b837 %ab = sub i128 %a, %b838 %ba = sub i128 %b, %a839 %sel = select i1 %cmp, i128 %ab, i128 %ba840 ret i128 %sel841}842 843;844; abs(sub_nsw(x, y)) -> abds(a,b)845;846 847define i8 @abd_subnsw_i8(i8 %a, i8 %b) nounwind {848; X86-LABEL: abd_subnsw_i8:849; X86: # %bb.0:850; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax851; X86-NEXT: subb {{[0-9]+}}(%esp), %al852; X86-NEXT: movl %eax, %ecx853; X86-NEXT: sarb $7, %cl854; X86-NEXT: xorb %cl, %al855; X86-NEXT: subb %cl, %al856; X86-NEXT: retl857;858; X64-LABEL: abd_subnsw_i8:859; X64: # %bb.0:860; X64-NEXT: movl %edi, %eax861; X64-NEXT: subb %sil, %al862; X64-NEXT: movl %eax, %ecx863; X64-NEXT: sarb $7, %cl864; X64-NEXT: xorb %cl, %al865; X64-NEXT: subb %cl, %al866; X64-NEXT: # kill: def $al killed $al killed $eax867; X64-NEXT: retq868 %sub = sub nsw i8 %a, %b869 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 false)870 ret i8 %abs871}872 873define i8 @abd_subnsw_i8_undef(i8 %a, i8 %b) nounwind {874; X86-LABEL: abd_subnsw_i8_undef:875; X86: # %bb.0:876; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax877; X86-NEXT: subb {{[0-9]+}}(%esp), %al878; X86-NEXT: movl %eax, %ecx879; X86-NEXT: sarb $7, %cl880; X86-NEXT: xorb %cl, %al881; X86-NEXT: subb %cl, %al882; X86-NEXT: retl883;884; X64-LABEL: abd_subnsw_i8_undef:885; X64: # %bb.0:886; X64-NEXT: movl %edi, %eax887; X64-NEXT: subb %sil, %al888; X64-NEXT: movl %eax, %ecx889; X64-NEXT: sarb $7, %cl890; X64-NEXT: xorb %cl, %al891; X64-NEXT: subb %cl, %al892; X64-NEXT: # kill: def $al killed $al killed $eax893; X64-NEXT: retq894 %sub = sub nsw i8 %a, %b895 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 true)896 ret i8 %abs897}898 899define i16 @abd_subnsw_i16(i16 %a, i16 %b) nounwind {900; X86-LABEL: abd_subnsw_i16:901; X86: # %bb.0:902; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx903; X86-NEXT: subw {{[0-9]+}}(%esp), %cx904; X86-NEXT: movl %ecx, %eax905; X86-NEXT: negw %ax906; X86-NEXT: cmovsw %cx, %ax907; X86-NEXT: retl908;909; X64-LABEL: abd_subnsw_i16:910; X64: # %bb.0:911; X64-NEXT: subl %esi, %edi912; X64-NEXT: movl %edi, %eax913; X64-NEXT: negw %ax914; X64-NEXT: cmovsw %di, %ax915; X64-NEXT: retq916 %sub = sub nsw i16 %a, %b917 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 false)918 ret i16 %abs919}920 921define i16 @abd_subnsw_i16_undef(i16 %a, i16 %b) nounwind {922; X86-LABEL: abd_subnsw_i16_undef:923; X86: # %bb.0:924; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx925; X86-NEXT: subw {{[0-9]+}}(%esp), %cx926; X86-NEXT: movl %ecx, %eax927; X86-NEXT: negw %ax928; X86-NEXT: cmovsw %cx, %ax929; X86-NEXT: retl930;931; X64-LABEL: abd_subnsw_i16_undef:932; X64: # %bb.0:933; X64-NEXT: subl %esi, %edi934; X64-NEXT: movl %edi, %eax935; X64-NEXT: negw %ax936; X64-NEXT: cmovsw %di, %ax937; X64-NEXT: retq938 %sub = sub nsw i16 %a, %b939 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 true)940 ret i16 %abs941}942 943define i32 @abd_subnsw_i32(i32 %a, i32 %b) nounwind {944; X86-LABEL: abd_subnsw_i32:945; X86: # %bb.0:946; X86-NEXT: movl {{[0-9]+}}(%esp), %eax947; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx948; X86-NEXT: movl %ecx, %edx949; X86-NEXT: subl %eax, %edx950; X86-NEXT: subl %ecx, %eax951; X86-NEXT: cmovll %edx, %eax952; X86-NEXT: retl953;954; X64-LABEL: abd_subnsw_i32:955; X64: # %bb.0:956; X64-NEXT: movl %edi, %eax957; X64-NEXT: subl %esi, %eax958; X64-NEXT: subl %edi, %esi959; X64-NEXT: cmovgel %esi, %eax960; X64-NEXT: retq961 %sub = sub nsw i32 %a, %b962 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)963 ret i32 %abs964}965 966define i32 @abd_subnsw_i32_undef(i32 %a, i32 %b) nounwind {967; X86-LABEL: abd_subnsw_i32_undef:968; X86: # %bb.0:969; X86-NEXT: movl {{[0-9]+}}(%esp), %eax970; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx971; X86-NEXT: movl %ecx, %edx972; X86-NEXT: subl %eax, %edx973; X86-NEXT: subl %ecx, %eax974; X86-NEXT: cmovll %edx, %eax975; X86-NEXT: retl976;977; X64-LABEL: abd_subnsw_i32_undef:978; X64: # %bb.0:979; X64-NEXT: movl %edi, %eax980; X64-NEXT: subl %esi, %eax981; X64-NEXT: subl %edi, %esi982; X64-NEXT: cmovgel %esi, %eax983; X64-NEXT: retq984 %sub = sub nsw i32 %a, %b985 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 true)986 ret i32 %abs987}988 989define i64 @abd_subnsw_i64(i64 %a, i64 %b) nounwind {990; X86-LABEL: abd_subnsw_i64:991; X86: # %bb.0:992; X86-NEXT: movl {{[0-9]+}}(%esp), %eax993; X86-NEXT: movl {{[0-9]+}}(%esp), %edx994; X86-NEXT: subl {{[0-9]+}}(%esp), %eax995; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx996; X86-NEXT: movl %edx, %ecx997; X86-NEXT: sarl $31, %ecx998; X86-NEXT: xorl %ecx, %edx999; X86-NEXT: xorl %ecx, %eax1000; X86-NEXT: subl %ecx, %eax1001; X86-NEXT: sbbl %ecx, %edx1002; X86-NEXT: retl1003;1004; X64-LABEL: abd_subnsw_i64:1005; X64: # %bb.0:1006; X64-NEXT: movq %rdi, %rax1007; X64-NEXT: subq %rsi, %rax1008; X64-NEXT: subq %rdi, %rsi1009; X64-NEXT: cmovgeq %rsi, %rax1010; X64-NEXT: retq1011 %sub = sub nsw i64 %a, %b1012 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false)1013 ret i64 %abs1014}1015 1016define i64 @abd_subnsw_i64_undef(i64 %a, i64 %b) nounwind {1017; X86-LABEL: abd_subnsw_i64_undef:1018; X86: # %bb.0:1019; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1020; X86-NEXT: movl {{[0-9]+}}(%esp), %edx1021; X86-NEXT: subl {{[0-9]+}}(%esp), %eax1022; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx1023; X86-NEXT: movl %edx, %ecx1024; X86-NEXT: sarl $31, %ecx1025; X86-NEXT: xorl %ecx, %edx1026; X86-NEXT: xorl %ecx, %eax1027; X86-NEXT: subl %ecx, %eax1028; X86-NEXT: sbbl %ecx, %edx1029; X86-NEXT: retl1030;1031; X64-LABEL: abd_subnsw_i64_undef:1032; X64: # %bb.0:1033; X64-NEXT: movq %rdi, %rax1034; X64-NEXT: subq %rsi, %rax1035; X64-NEXT: subq %rdi, %rsi1036; X64-NEXT: cmovgeq %rsi, %rax1037; X64-NEXT: retq1038 %sub = sub nsw i64 %a, %b1039 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true)1040 ret i64 %abs1041}1042 1043define i128 @abd_subnsw_i128(i128 %a, i128 %b) nounwind {1044; X86-LABEL: abd_subnsw_i128:1045; X86: # %bb.0:1046; X86-NEXT: pushl %ebp1047; X86-NEXT: movl %esp, %ebp1048; X86-NEXT: pushl %edi1049; X86-NEXT: pushl %esi1050; X86-NEXT: andl $-16, %esp1051; X86-NEXT: movl 32(%ebp), %edx1052; X86-NEXT: movl 36(%ebp), %ecx1053; X86-NEXT: movl 24(%ebp), %edi1054; X86-NEXT: movl 28(%ebp), %esi1055; X86-NEXT: subl 40(%ebp), %edi1056; X86-NEXT: sbbl 44(%ebp), %esi1057; X86-NEXT: sbbl 48(%ebp), %edx1058; X86-NEXT: sbbl 52(%ebp), %ecx1059; X86-NEXT: movl %ecx, %eax1060; X86-NEXT: sarl $31, %eax1061; X86-NEXT: xorl %eax, %ecx1062; X86-NEXT: xorl %eax, %edx1063; X86-NEXT: xorl %eax, %esi1064; X86-NEXT: xorl %eax, %edi1065; X86-NEXT: subl %eax, %edi1066; X86-NEXT: sbbl %eax, %esi1067; X86-NEXT: sbbl %eax, %edx1068; X86-NEXT: sbbl %eax, %ecx1069; X86-NEXT: movl 8(%ebp), %eax1070; X86-NEXT: movl %edi, (%eax)1071; X86-NEXT: movl %esi, 4(%eax)1072; X86-NEXT: movl %edx, 8(%eax)1073; X86-NEXT: movl %ecx, 12(%eax)1074; X86-NEXT: leal -8(%ebp), %esp1075; X86-NEXT: popl %esi1076; X86-NEXT: popl %edi1077; X86-NEXT: popl %ebp1078; X86-NEXT: retl $41079;1080; X64-LABEL: abd_subnsw_i128:1081; X64: # %bb.0:1082; X64-NEXT: movq %rdi, %rax1083; X64-NEXT: subq %rdx, %rax1084; X64-NEXT: sbbq %rcx, %rsi1085; X64-NEXT: movq %rsi, %rcx1086; X64-NEXT: sarq $63, %rcx1087; X64-NEXT: xorq %rcx, %rsi1088; X64-NEXT: xorq %rcx, %rax1089; X64-NEXT: subq %rcx, %rax1090; X64-NEXT: sbbq %rcx, %rsi1091; X64-NEXT: movq %rsi, %rdx1092; X64-NEXT: retq1093 %sub = sub nsw i128 %a, %b1094 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)1095 ret i128 %abs1096}1097 1098define i128 @abd_subnsw_i128_undef(i128 %a, i128 %b) nounwind {1099; X86-LABEL: abd_subnsw_i128_undef:1100; X86: # %bb.0:1101; X86-NEXT: pushl %ebp1102; X86-NEXT: movl %esp, %ebp1103; X86-NEXT: pushl %edi1104; X86-NEXT: pushl %esi1105; X86-NEXT: andl $-16, %esp1106; X86-NEXT: movl 32(%ebp), %edx1107; X86-NEXT: movl 36(%ebp), %ecx1108; X86-NEXT: movl 24(%ebp), %edi1109; X86-NEXT: movl 28(%ebp), %esi1110; X86-NEXT: subl 40(%ebp), %edi1111; X86-NEXT: sbbl 44(%ebp), %esi1112; X86-NEXT: sbbl 48(%ebp), %edx1113; X86-NEXT: sbbl 52(%ebp), %ecx1114; X86-NEXT: movl %ecx, %eax1115; X86-NEXT: sarl $31, %eax1116; X86-NEXT: xorl %eax, %ecx1117; X86-NEXT: xorl %eax, %edx1118; X86-NEXT: xorl %eax, %esi1119; X86-NEXT: xorl %eax, %edi1120; X86-NEXT: subl %eax, %edi1121; X86-NEXT: sbbl %eax, %esi1122; X86-NEXT: sbbl %eax, %edx1123; X86-NEXT: sbbl %eax, %ecx1124; X86-NEXT: movl 8(%ebp), %eax1125; X86-NEXT: movl %edi, (%eax)1126; X86-NEXT: movl %esi, 4(%eax)1127; X86-NEXT: movl %edx, 8(%eax)1128; X86-NEXT: movl %ecx, 12(%eax)1129; X86-NEXT: leal -8(%ebp), %esp1130; X86-NEXT: popl %esi1131; X86-NEXT: popl %edi1132; X86-NEXT: popl %ebp1133; X86-NEXT: retl $41134;1135; X64-LABEL: abd_subnsw_i128_undef:1136; X64: # %bb.0:1137; X64-NEXT: movq %rdi, %rax1138; X64-NEXT: subq %rdx, %rax1139; X64-NEXT: sbbq %rcx, %rsi1140; X64-NEXT: movq %rsi, %rcx1141; X64-NEXT: sarq $63, %rcx1142; X64-NEXT: xorq %rcx, %rsi1143; X64-NEXT: xorq %rcx, %rax1144; X64-NEXT: subq %rcx, %rax1145; X64-NEXT: sbbq %rcx, %rsi1146; X64-NEXT: movq %rsi, %rdx1147; X64-NEXT: retq1148 %sub = sub nsw i128 %a, %b1149 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)1150 ret i128 %abs1151}1152 1153;1154; negative tests1155;1156 1157define i32 @abd_sub_i32(i32 %a, i32 %b) nounwind {1158; X86-LABEL: abd_sub_i32:1159; X86: # %bb.0:1160; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1161; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1162; X86-NEXT: movl %ecx, %eax1163; X86-NEXT: negl %eax1164; X86-NEXT: cmovsl %ecx, %eax1165; X86-NEXT: retl1166;1167; X64-LABEL: abd_sub_i32:1168; X64: # %bb.0:1169; X64-NEXT: subl %esi, %edi1170; X64-NEXT: movl %edi, %eax1171; X64-NEXT: negl %eax1172; X64-NEXT: cmovsl %edi, %eax1173; X64-NEXT: retq1174 %sub = sub i32 %a, %b1175 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false)1176 ret i32 %abs1177}1178 1179;1180; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abds(a,b)1181;1182 1183define i8 @abd_select_i8(i8 %a, i8 %b) nounwind {1184; X86-LABEL: abd_select_i8:1185; X86: # %bb.0:1186; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax1187; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx1188; X86-NEXT: movl %ecx, %edx1189; X86-NEXT: subl %eax, %edx1190; X86-NEXT: subl %ecx, %eax1191; X86-NEXT: cmovll %edx, %eax1192; X86-NEXT: # kill: def $al killed $al killed $eax1193; X86-NEXT: retl1194;1195; X64-LABEL: abd_select_i8:1196; X64: # %bb.0:1197; X64-NEXT: movsbl %sil, %eax1198; X64-NEXT: movsbl %dil, %ecx1199; X64-NEXT: movl %ecx, %edx1200; X64-NEXT: subl %eax, %edx1201; X64-NEXT: subl %ecx, %eax1202; X64-NEXT: cmovll %edx, %eax1203; X64-NEXT: # kill: def $al killed $al killed $eax1204; X64-NEXT: retq1205 %cmp = icmp slt i8 %a, %b1206 %ab = select i1 %cmp, i8 %a, i8 %b1207 %ba = select i1 %cmp, i8 %b, i8 %a1208 %sub = sub i8 %ba, %ab1209 ret i8 %sub1210}1211 1212define i16 @abd_select_i16(i16 %a, i16 %b) nounwind {1213; X86-LABEL: abd_select_i16:1214; X86: # %bb.0:1215; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax1216; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx1217; X86-NEXT: movl %ecx, %edx1218; X86-NEXT: subl %eax, %edx1219; X86-NEXT: subl %ecx, %eax1220; X86-NEXT: cmovll %edx, %eax1221; X86-NEXT: # kill: def $ax killed $ax killed $eax1222; X86-NEXT: retl1223;1224; X64-LABEL: abd_select_i16:1225; X64: # %bb.0:1226; X64-NEXT: movswl %si, %eax1227; X64-NEXT: movswl %di, %ecx1228; X64-NEXT: movl %ecx, %edx1229; X64-NEXT: subl %eax, %edx1230; X64-NEXT: subl %ecx, %eax1231; X64-NEXT: cmovll %edx, %eax1232; X64-NEXT: # kill: def $ax killed $ax killed $eax1233; X64-NEXT: retq1234 %cmp = icmp sle i16 %a, %b1235 %ab = select i1 %cmp, i16 %a, i16 %b1236 %ba = select i1 %cmp, i16 %b, i16 %a1237 %sub = sub i16 %ba, %ab1238 ret i16 %sub1239}1240 1241define i32 @abd_select_i32(i32 %a, i32 %b) nounwind {1242; X86-LABEL: abd_select_i32:1243; X86: # %bb.0:1244; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1245; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1246; X86-NEXT: movl %ecx, %edx1247; X86-NEXT: subl %eax, %edx1248; X86-NEXT: subl %ecx, %eax1249; X86-NEXT: cmovll %edx, %eax1250; X86-NEXT: retl1251;1252; X64-LABEL: abd_select_i32:1253; X64: # %bb.0:1254; X64-NEXT: movl %edi, %eax1255; X64-NEXT: subl %esi, %eax1256; X64-NEXT: subl %edi, %esi1257; X64-NEXT: cmovgel %esi, %eax1258; X64-NEXT: retq1259 %cmp = icmp sgt i32 %a, %b1260 %ab = select i1 %cmp, i32 %a, i32 %b1261 %ba = select i1 %cmp, i32 %b, i32 %a1262 %sub = sub i32 %ab, %ba1263 ret i32 %sub1264}1265 1266define i64 @abd_select_i64(i64 %a, i64 %b) nounwind {1267; X86-LABEL: abd_select_i64:1268; X86: # %bb.0:1269; X86-NEXT: pushl %ebx1270; X86-NEXT: pushl %edi1271; X86-NEXT: pushl %esi1272; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1273; X86-NEXT: movl {{[0-9]+}}(%esp), %edx1274; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1275; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1276; X86-NEXT: movl %ecx, %edi1277; X86-NEXT: subl %eax, %edi1278; X86-NEXT: movl %esi, %ebx1279; X86-NEXT: sbbl %edx, %ebx1280; X86-NEXT: subl %ecx, %eax1281; X86-NEXT: sbbl %esi, %edx1282; X86-NEXT: cmovll %edi, %eax1283; X86-NEXT: cmovll %ebx, %edx1284; X86-NEXT: popl %esi1285; X86-NEXT: popl %edi1286; X86-NEXT: popl %ebx1287; X86-NEXT: retl1288;1289; X64-LABEL: abd_select_i64:1290; X64: # %bb.0:1291; X64-NEXT: movq %rdi, %rax1292; X64-NEXT: subq %rsi, %rax1293; X64-NEXT: subq %rdi, %rsi1294; X64-NEXT: cmovgeq %rsi, %rax1295; X64-NEXT: retq1296 %cmp = icmp sge i64 %a, %b1297 %ab = select i1 %cmp, i64 %a, i64 %b1298 %ba = select i1 %cmp, i64 %b, i64 %a1299 %sub = sub i64 %ab, %ba1300 ret i64 %sub1301}1302 1303define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {1304; X86-LABEL: abd_select_i128:1305; X86: # %bb.0:1306; X86-NEXT: pushl %ebp1307; X86-NEXT: movl %esp, %ebp1308; X86-NEXT: pushl %ebx1309; X86-NEXT: pushl %edi1310; X86-NEXT: pushl %esi1311; X86-NEXT: andl $-16, %esp1312; X86-NEXT: subl $16, %esp1313; X86-NEXT: movl 40(%ebp), %ecx1314; X86-NEXT: movl 44(%ebp), %edx1315; X86-NEXT: movl 24(%ebp), %eax1316; X86-NEXT: movl 28(%ebp), %esi1317; X86-NEXT: subl %ecx, %eax1318; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1319; X86-NEXT: movl %esi, %eax1320; X86-NEXT: sbbl %edx, %eax1321; X86-NEXT: movl %eax, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill1322; X86-NEXT: movl 48(%ebp), %esi1323; X86-NEXT: movl 32(%ebp), %edi1324; X86-NEXT: sbbl %esi, %edi1325; X86-NEXT: movl 52(%ebp), %ebx1326; X86-NEXT: movl 36(%ebp), %eax1327; X86-NEXT: sbbl %ebx, %eax1328; X86-NEXT: subl 24(%ebp), %ecx1329; X86-NEXT: sbbl 28(%ebp), %edx1330; X86-NEXT: sbbl 32(%ebp), %esi1331; X86-NEXT: sbbl 36(%ebp), %ebx1332; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %ecx # 4-byte Folded Reload1333; X86-NEXT: cmovll {{[-0-9]+}}(%e{{[sb]}}p), %edx # 4-byte Folded Reload1334; X86-NEXT: cmovll %edi, %esi1335; X86-NEXT: cmovll %eax, %ebx1336; X86-NEXT: movl 8(%ebp), %eax1337; X86-NEXT: movl %ebx, 12(%eax)1338; X86-NEXT: movl %esi, 8(%eax)1339; X86-NEXT: movl %edx, 4(%eax)1340; X86-NEXT: movl %ecx, (%eax)1341; X86-NEXT: leal -12(%ebp), %esp1342; X86-NEXT: popl %esi1343; X86-NEXT: popl %edi1344; X86-NEXT: popl %ebx1345; X86-NEXT: popl %ebp1346; X86-NEXT: retl $41347;1348; X64-LABEL: abd_select_i128:1349; X64: # %bb.0:1350; X64-NEXT: movq %rdi, %rax1351; X64-NEXT: subq %rdx, %rax1352; X64-NEXT: movq %rsi, %r81353; X64-NEXT: sbbq %rcx, %r81354; X64-NEXT: subq %rdi, %rdx1355; X64-NEXT: sbbq %rsi, %rcx1356; X64-NEXT: cmovgeq %rdx, %rax1357; X64-NEXT: cmovgeq %rcx, %r81358; X64-NEXT: movq %r8, %rdx1359; X64-NEXT: retq1360 %cmp = icmp slt i128 %a, %b1361 %ab = select i1 %cmp, i128 %a, i128 %b1362 %ba = select i1 %cmp, i128 %b, i128 %a1363 %sub = sub i128 %ba, %ab1364 ret i128 %sub1365}1366 1367declare i8 @llvm.abs.i8(i8, i1)1368declare i16 @llvm.abs.i16(i16, i1)1369declare i32 @llvm.abs.i32(i32, i1)1370declare i64 @llvm.abs.i64(i64, i1)1371declare i128 @llvm.abs.i128(i128, i1)1372 1373declare i8 @llvm.smax.i8(i8, i8)1374declare i16 @llvm.smax.i16(i16, i16)1375declare i32 @llvm.smax.i32(i32, i32)1376declare i64 @llvm.smax.i64(i64, i64)1377 1378declare i8 @llvm.smin.i8(i8, i8)1379declare i16 @llvm.smin.i16(i16, i16)1380declare i32 @llvm.smin.i32(i32, i32)1381declare i64 @llvm.smin.i64(i64, i64)1382