971 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(zext(a),zext(b)))) -> abdu(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: movzbl {{[0-9]+}}(%esp), %eax13; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx14; X86-NEXT: movl %ecx, %edx15; X86-NEXT: subl %eax, %edx16; X86-NEXT: subl %ecx, %eax17; X86-NEXT: cmovbl %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: movzbl %sil, %eax24; X64-NEXT: movzbl %dil, %ecx25; X64-NEXT: movl %ecx, %edx26; X64-NEXT: subl %eax, %edx27; X64-NEXT: subl %ecx, %eax28; X64-NEXT: cmovbl %edx, %eax29; X64-NEXT: # kill: def $al killed $al killed $eax30; X64-NEXT: retq31 %aext = zext i8 %a to i6432 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax43; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx44; X86-NEXT: movl %ecx, %edx45; X86-NEXT: subl %eax, %edx46; X86-NEXT: subl %ecx, %eax47; X86-NEXT: cmovbl %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: movzbl %dil, %ecx54; X64-NEXT: subl %esi, %edi55; X64-NEXT: movzwl %si, %eax56; X64-NEXT: subl %ecx, %eax57; X64-NEXT: cmovbl %edi, %eax58; X64-NEXT: # kill: def $al killed $al killed $eax59; X64-NEXT: retq60 %aext = zext i8 %a to i6461 %bext = zext 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: movzbl {{[0-9]+}}(%esp), %eax72; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx73; X86-NEXT: movl %ecx, %edx74; X86-NEXT: subl %eax, %edx75; X86-NEXT: subl %ecx, %eax76; X86-NEXT: cmovbl %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: movzbl %sil, %eax83; X64-NEXT: movzbl %dil, %ecx84; X64-NEXT: movl %ecx, %edx85; X64-NEXT: subl %eax, %edx86; X64-NEXT: subl %ecx, %eax87; X64-NEXT: cmovbl %edx, %eax88; X64-NEXT: # kill: def $al killed $al killed $eax89; X64-NEXT: retq90 %aext = zext i8 %a to i6491 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax102; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx103; X86-NEXT: movl %ecx, %edx104; X86-NEXT: subl %eax, %edx105; X86-NEXT: subl %ecx, %eax106; X86-NEXT: cmovbl %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: movzwl %si, %eax113; X64-NEXT: movzwl %di, %ecx114; X64-NEXT: movl %ecx, %edx115; X64-NEXT: subl %eax, %edx116; X64-NEXT: subl %ecx, %eax117; X64-NEXT: cmovbl %edx, %eax118; X64-NEXT: # kill: def $ax killed $ax killed $eax119; X64-NEXT: retq120 %aext = zext i16 %a to i64121 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %ecx133; X86-NEXT: movl %ecx, %edx134; X86-NEXT: subl %eax, %edx135; X86-NEXT: subl %ecx, %eax136; X86-NEXT: cmovbl %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: movzwl %di, %ecx143; X64-NEXT: movl %edi, %eax144; X64-NEXT: subl %esi, %eax145; X64-NEXT: subl %ecx, %esi146; X64-NEXT: cmovael %esi, %eax147; X64-NEXT: # kill: def $ax killed $ax killed $eax148; X64-NEXT: retq149 %aext = zext i16 %a to i64150 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax161; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx162; X86-NEXT: movl %ecx, %edx163; X86-NEXT: subl %eax, %edx164; X86-NEXT: subl %ecx, %eax165; X86-NEXT: cmovbl %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: movzwl %si, %eax172; X64-NEXT: movzwl %di, %ecx173; X64-NEXT: movl %ecx, %edx174; X64-NEXT: subl %eax, %edx175; X64-NEXT: subl %ecx, %eax176; X64-NEXT: cmovbl %edx, %eax177; X64-NEXT: # kill: def $ax killed $ax killed $eax178; X64-NEXT: retq179 %aext = zext i16 %a to i64180 %bext = zext 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: cmovbl %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: cmovael %esi, %eax204; X64-NEXT: retq205 %aext = zext i32 %a to i64206 %bext = zext 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: movzwl {{[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: cmovbl %edx, %eax222; X86-NEXT: retl223;224; X64-LABEL: abd_ext_i32_i16:225; X64: # %bb.0:226; X64-NEXT: movzwl %si, %eax227; X64-NEXT: movl %edi, %ecx228; X64-NEXT: subl %eax, %ecx229; X64-NEXT: subl %edi, %eax230; X64-NEXT: cmovbl %ecx, %eax231; X64-NEXT: retq232 %aext = zext i32 %a to i64233 %bext = zext 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: cmovbl %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: cmovael %esi, %eax257; X64-NEXT: retq258 %aext = zext i32 %a to i64259 %bext = zext 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: movl {{[0-9]+}}(%esp), %eax270; X86-NEXT: movl {{[0-9]+}}(%esp), %edx271; X86-NEXT: xorl %ecx, %ecx272; X86-NEXT: subl {{[0-9]+}}(%esp), %eax273; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx274; X86-NEXT: sbbl %ecx, %ecx275; X86-NEXT: xorl %ecx, %edx276; X86-NEXT: xorl %ecx, %eax277; X86-NEXT: subl %ecx, %eax278; X86-NEXT: sbbl %ecx, %edx279; X86-NEXT: retl280;281; X64-LABEL: abd_ext_i64:282; X64: # %bb.0:283; X64-NEXT: movq %rdi, %rax284; X64-NEXT: subq %rsi, %rax285; X64-NEXT: subq %rdi, %rsi286; X64-NEXT: cmovaeq %rsi, %rax287; X64-NEXT: retq288 %aext = zext i64 %a to i128289 %bext = zext i64 %b to i128290 %sub = sub i128 %aext, %bext291 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false)292 %trunc = trunc i128 %abs to i64293 ret i64 %trunc294}295 296define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind {297; X86-LABEL: abd_ext_i64_undef:298; X86: # %bb.0:299; X86-NEXT: movl {{[0-9]+}}(%esp), %eax300; X86-NEXT: movl {{[0-9]+}}(%esp), %edx301; X86-NEXT: xorl %ecx, %ecx302; X86-NEXT: subl {{[0-9]+}}(%esp), %eax303; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx304; X86-NEXT: sbbl %ecx, %ecx305; X86-NEXT: xorl %ecx, %edx306; X86-NEXT: xorl %ecx, %eax307; X86-NEXT: subl %ecx, %eax308; X86-NEXT: sbbl %ecx, %edx309; X86-NEXT: retl310;311; X64-LABEL: abd_ext_i64_undef:312; X64: # %bb.0:313; X64-NEXT: movq %rdi, %rax314; X64-NEXT: subq %rsi, %rax315; X64-NEXT: subq %rdi, %rsi316; X64-NEXT: cmovaeq %rsi, %rax317; X64-NEXT: retq318 %aext = zext i64 %a to i128319 %bext = zext i64 %b to i128320 %sub = sub i128 %aext, %bext321 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true)322 %trunc = trunc i128 %abs to i64323 ret i64 %trunc324}325 326define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {327; X86-LABEL: abd_ext_i128:328; X86: # %bb.0:329; X86-NEXT: pushl %ebp330; X86-NEXT: movl %esp, %ebp331; X86-NEXT: pushl %edi332; X86-NEXT: pushl %esi333; X86-NEXT: andl $-16, %esp334; X86-NEXT: movl 32(%ebp), %edx335; X86-NEXT: movl 36(%ebp), %ecx336; X86-NEXT: movl 24(%ebp), %edi337; X86-NEXT: movl 28(%ebp), %esi338; X86-NEXT: xorl %eax, %eax339; X86-NEXT: subl 40(%ebp), %edi340; X86-NEXT: sbbl 44(%ebp), %esi341; X86-NEXT: sbbl 48(%ebp), %edx342; X86-NEXT: sbbl 52(%ebp), %ecx343; X86-NEXT: sbbl %eax, %eax344; X86-NEXT: xorl %eax, %ecx345; X86-NEXT: xorl %eax, %edx346; X86-NEXT: xorl %eax, %esi347; X86-NEXT: xorl %eax, %edi348; X86-NEXT: subl %eax, %edi349; X86-NEXT: sbbl %eax, %esi350; X86-NEXT: sbbl %eax, %edx351; X86-NEXT: sbbl %eax, %ecx352; X86-NEXT: movl 8(%ebp), %eax353; X86-NEXT: movl %edi, (%eax)354; X86-NEXT: movl %esi, 4(%eax)355; X86-NEXT: movl %edx, 8(%eax)356; X86-NEXT: movl %ecx, 12(%eax)357; X86-NEXT: leal -8(%ebp), %esp358; X86-NEXT: popl %esi359; X86-NEXT: popl %edi360; X86-NEXT: popl %ebp361; X86-NEXT: retl $4362;363; X64-LABEL: abd_ext_i128:364; X64: # %bb.0:365; X64-NEXT: movq %rdi, %rax366; X64-NEXT: xorl %edi, %edi367; X64-NEXT: subq %rdx, %rax368; X64-NEXT: sbbq %rcx, %rsi369; X64-NEXT: sbbq %rdi, %rdi370; X64-NEXT: xorq %rdi, %rsi371; X64-NEXT: xorq %rdi, %rax372; X64-NEXT: subq %rdi, %rax373; X64-NEXT: sbbq %rdi, %rsi374; X64-NEXT: movq %rsi, %rdx375; X64-NEXT: retq376 %aext = zext i128 %a to i256377 %bext = zext i128 %b to i256378 %sub = sub i256 %aext, %bext379 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false)380 %trunc = trunc i256 %abs to i128381 ret i128 %trunc382}383 384define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {385; X86-LABEL: abd_ext_i128_undef:386; X86: # %bb.0:387; X86-NEXT: pushl %ebp388; X86-NEXT: movl %esp, %ebp389; X86-NEXT: pushl %edi390; X86-NEXT: pushl %esi391; X86-NEXT: andl $-16, %esp392; X86-NEXT: movl 32(%ebp), %edx393; X86-NEXT: movl 36(%ebp), %ecx394; X86-NEXT: movl 24(%ebp), %edi395; X86-NEXT: movl 28(%ebp), %esi396; X86-NEXT: xorl %eax, %eax397; X86-NEXT: subl 40(%ebp), %edi398; X86-NEXT: sbbl 44(%ebp), %esi399; X86-NEXT: sbbl 48(%ebp), %edx400; X86-NEXT: sbbl 52(%ebp), %ecx401; X86-NEXT: sbbl %eax, %eax402; X86-NEXT: xorl %eax, %ecx403; X86-NEXT: xorl %eax, %edx404; X86-NEXT: xorl %eax, %esi405; X86-NEXT: xorl %eax, %edi406; X86-NEXT: subl %eax, %edi407; X86-NEXT: sbbl %eax, %esi408; X86-NEXT: sbbl %eax, %edx409; X86-NEXT: sbbl %eax, %ecx410; X86-NEXT: movl 8(%ebp), %eax411; X86-NEXT: movl %edi, (%eax)412; X86-NEXT: movl %esi, 4(%eax)413; X86-NEXT: movl %edx, 8(%eax)414; X86-NEXT: movl %ecx, 12(%eax)415; X86-NEXT: leal -8(%ebp), %esp416; X86-NEXT: popl %esi417; X86-NEXT: popl %edi418; X86-NEXT: popl %ebp419; X86-NEXT: retl $4420;421; X64-LABEL: abd_ext_i128_undef:422; X64: # %bb.0:423; X64-NEXT: movq %rdi, %rax424; X64-NEXT: xorl %edi, %edi425; X64-NEXT: subq %rdx, %rax426; X64-NEXT: sbbq %rcx, %rsi427; X64-NEXT: sbbq %rdi, %rdi428; X64-NEXT: xorq %rdi, %rsi429; X64-NEXT: xorq %rdi, %rax430; X64-NEXT: subq %rdi, %rax431; X64-NEXT: sbbq %rdi, %rsi432; X64-NEXT: movq %rsi, %rdx433; X64-NEXT: retq434 %aext = zext i128 %a to i256435 %bext = zext i128 %b to i256436 %sub = sub i256 %aext, %bext437 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true)438 %trunc = trunc i256 %abs to i128439 ret i128 %trunc440}441 442;443; sub(umax(a,b),umin(a,b)) -> abdu(a,b)444;445 446define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind {447; X86-LABEL: abd_minmax_i8:448; X86: # %bb.0:449; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax450; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx451; X86-NEXT: movl %ecx, %edx452; X86-NEXT: subl %eax, %edx453; X86-NEXT: subl %ecx, %eax454; X86-NEXT: cmovbl %edx, %eax455; X86-NEXT: # kill: def $al killed $al killed $eax456; X86-NEXT: retl457;458; X64-LABEL: abd_minmax_i8:459; X64: # %bb.0:460; X64-NEXT: movzbl %sil, %eax461; X64-NEXT: movzbl %dil, %ecx462; X64-NEXT: movl %ecx, %edx463; X64-NEXT: subl %eax, %edx464; X64-NEXT: subl %ecx, %eax465; X64-NEXT: cmovbl %edx, %eax466; X64-NEXT: # kill: def $al killed $al killed $eax467; X64-NEXT: retq468 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b)469 %max = call i8 @llvm.umax.i8(i8 %a, i8 %b)470 %sub = sub i8 %max, %min471 ret i8 %sub472}473 474define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind {475; X86-LABEL: abd_minmax_i16:476; X86: # %bb.0:477; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax478; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx479; X86-NEXT: movl %ecx, %edx480; X86-NEXT: subl %eax, %edx481; X86-NEXT: subl %ecx, %eax482; X86-NEXT: cmovbl %edx, %eax483; X86-NEXT: # kill: def $ax killed $ax killed $eax484; X86-NEXT: retl485;486; X64-LABEL: abd_minmax_i16:487; X64: # %bb.0:488; X64-NEXT: movzwl %si, %eax489; X64-NEXT: movzwl %di, %ecx490; X64-NEXT: movl %ecx, %edx491; X64-NEXT: subl %eax, %edx492; X64-NEXT: subl %ecx, %eax493; X64-NEXT: cmovbl %edx, %eax494; X64-NEXT: # kill: def $ax killed $ax killed $eax495; X64-NEXT: retq496 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b)497 %max = call i16 @llvm.umax.i16(i16 %a, i16 %b)498 %sub = sub i16 %max, %min499 ret i16 %sub500}501 502define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind {503; X86-LABEL: abd_minmax_i32:504; X86: # %bb.0:505; X86-NEXT: movl {{[0-9]+}}(%esp), %eax506; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx507; X86-NEXT: movl %ecx, %edx508; X86-NEXT: subl %eax, %edx509; X86-NEXT: subl %ecx, %eax510; X86-NEXT: cmovbl %edx, %eax511; X86-NEXT: retl512;513; X64-LABEL: abd_minmax_i32:514; X64: # %bb.0:515; X64-NEXT: movl %edi, %eax516; X64-NEXT: subl %esi, %eax517; X64-NEXT: subl %edi, %esi518; X64-NEXT: cmovael %esi, %eax519; X64-NEXT: retq520 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b)521 %max = call i32 @llvm.umax.i32(i32 %a, i32 %b)522 %sub = sub i32 %max, %min523 ret i32 %sub524}525 526define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind {527; X86-LABEL: abd_minmax_i64:528; X86: # %bb.0:529; X86-NEXT: movl {{[0-9]+}}(%esp), %eax530; X86-NEXT: movl {{[0-9]+}}(%esp), %edx531; X86-NEXT: xorl %ecx, %ecx532; X86-NEXT: subl {{[0-9]+}}(%esp), %eax533; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx534; X86-NEXT: sbbl %ecx, %ecx535; X86-NEXT: xorl %ecx, %edx536; X86-NEXT: xorl %ecx, %eax537; X86-NEXT: subl %ecx, %eax538; X86-NEXT: sbbl %ecx, %edx539; X86-NEXT: retl540;541; X64-LABEL: abd_minmax_i64:542; X64: # %bb.0:543; X64-NEXT: movq %rdi, %rax544; X64-NEXT: subq %rsi, %rax545; X64-NEXT: subq %rdi, %rsi546; X64-NEXT: cmovaeq %rsi, %rax547; X64-NEXT: retq548 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b)549 %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)550 %sub = sub i64 %max, %min551 ret i64 %sub552}553 554define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {555; X86-LABEL: abd_minmax_i128:556; X86: # %bb.0:557; X86-NEXT: pushl %ebp558; X86-NEXT: movl %esp, %ebp559; X86-NEXT: pushl %edi560; X86-NEXT: pushl %esi561; X86-NEXT: andl $-16, %esp562; X86-NEXT: movl 32(%ebp), %edx563; X86-NEXT: movl 36(%ebp), %ecx564; X86-NEXT: movl 24(%ebp), %edi565; X86-NEXT: movl 28(%ebp), %esi566; X86-NEXT: xorl %eax, %eax567; X86-NEXT: subl 40(%ebp), %edi568; X86-NEXT: sbbl 44(%ebp), %esi569; X86-NEXT: sbbl 48(%ebp), %edx570; X86-NEXT: sbbl 52(%ebp), %ecx571; X86-NEXT: sbbl %eax, %eax572; X86-NEXT: xorl %eax, %ecx573; X86-NEXT: xorl %eax, %edx574; X86-NEXT: xorl %eax, %esi575; X86-NEXT: xorl %eax, %edi576; X86-NEXT: subl %eax, %edi577; X86-NEXT: sbbl %eax, %esi578; X86-NEXT: sbbl %eax, %edx579; X86-NEXT: sbbl %eax, %ecx580; X86-NEXT: movl 8(%ebp), %eax581; X86-NEXT: movl %edi, (%eax)582; X86-NEXT: movl %esi, 4(%eax)583; X86-NEXT: movl %edx, 8(%eax)584; X86-NEXT: movl %ecx, 12(%eax)585; X86-NEXT: leal -8(%ebp), %esp586; X86-NEXT: popl %esi587; X86-NEXT: popl %edi588; X86-NEXT: popl %ebp589; X86-NEXT: retl $4590;591; X64-LABEL: abd_minmax_i128:592; X64: # %bb.0:593; X64-NEXT: movq %rdi, %rax594; X64-NEXT: xorl %edi, %edi595; X64-NEXT: subq %rdx, %rax596; X64-NEXT: sbbq %rcx, %rsi597; X64-NEXT: sbbq %rdi, %rdi598; X64-NEXT: xorq %rdi, %rsi599; X64-NEXT: xorq %rdi, %rax600; X64-NEXT: subq %rdi, %rax601; X64-NEXT: sbbq %rdi, %rsi602; X64-NEXT: movq %rsi, %rdx603; X64-NEXT: retq604 %min = call i128 @llvm.umin.i128(i128 %a, i128 %b)605 %max = call i128 @llvm.umax.i128(i128 %a, i128 %b)606 %sub = sub i128 %max, %min607 ret i128 %sub608}609 610;611; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b)612;613 614define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind {615; X86-LABEL: abd_cmp_i8:616; X86: # %bb.0:617; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax618; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx619; X86-NEXT: movl %ecx, %edx620; X86-NEXT: subl %eax, %edx621; X86-NEXT: subl %ecx, %eax622; X86-NEXT: cmovbl %edx, %eax623; X86-NEXT: # kill: def $al killed $al killed $eax624; X86-NEXT: retl625;626; X64-LABEL: abd_cmp_i8:627; X64: # %bb.0:628; X64-NEXT: movzbl %dil, %eax629; X64-NEXT: movzbl %sil, %ecx630; X64-NEXT: movl %ecx, %edx631; X64-NEXT: subl %eax, %edx632; X64-NEXT: subl %ecx, %eax633; X64-NEXT: cmovbl %edx, %eax634; X64-NEXT: # kill: def $al killed $al killed $eax635; X64-NEXT: retq636 %cmp = icmp ugt i8 %a, %b637 %ab = sub i8 %a, %b638 %ba = sub i8 %b, %a639 %sel = select i1 %cmp, i8 %ab, i8 %ba640 ret i8 %sel641}642 643define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind {644; X86-LABEL: abd_cmp_i16:645; X86: # %bb.0:646; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax647; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx648; X86-NEXT: movl %ecx, %edx649; X86-NEXT: subl %eax, %edx650; X86-NEXT: subl %ecx, %eax651; X86-NEXT: cmovbl %edx, %eax652; X86-NEXT: # kill: def $ax killed $ax killed $eax653; X86-NEXT: retl654;655; X64-LABEL: abd_cmp_i16:656; X64: # %bb.0:657; X64-NEXT: movzwl %si, %eax658; X64-NEXT: movzwl %di, %ecx659; X64-NEXT: movl %ecx, %edx660; X64-NEXT: subl %eax, %edx661; X64-NEXT: subl %ecx, %eax662; X64-NEXT: cmovbl %edx, %eax663; X64-NEXT: # kill: def $ax killed $ax killed $eax664; X64-NEXT: retq665 %cmp = icmp uge i16 %a, %b666 %ab = sub i16 %a, %b667 %ba = sub i16 %b, %a668 %sel = select i1 %cmp, i16 %ab, i16 %ba669 ret i16 %sel670}671 672define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind {673; X86-LABEL: abd_cmp_i32:674; X86: # %bb.0:675; X86-NEXT: movl {{[0-9]+}}(%esp), %eax676; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx677; X86-NEXT: movl %ecx, %edx678; X86-NEXT: subl %eax, %edx679; X86-NEXT: subl %ecx, %eax680; X86-NEXT: cmovbl %edx, %eax681; X86-NEXT: retl682;683; X64-LABEL: abd_cmp_i32:684; X64: # %bb.0:685; X64-NEXT: movl %edi, %eax686; X64-NEXT: subl %esi, %eax687; X64-NEXT: subl %edi, %esi688; X64-NEXT: cmovael %esi, %eax689; X64-NEXT: retq690 %cmp = icmp ult i32 %a, %b691 %ab = sub i32 %a, %b692 %ba = sub i32 %b, %a693 %sel = select i1 %cmp, i32 %ba, i32 %ab694 ret i32 %sel695}696 697define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind {698; X86-LABEL: abd_cmp_i64:699; X86: # %bb.0:700; X86-NEXT: movl {{[0-9]+}}(%esp), %eax701; X86-NEXT: movl {{[0-9]+}}(%esp), %edx702; X86-NEXT: xorl %ecx, %ecx703; X86-NEXT: subl {{[0-9]+}}(%esp), %eax704; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx705; X86-NEXT: sbbl %ecx, %ecx706; X86-NEXT: xorl %ecx, %edx707; X86-NEXT: xorl %ecx, %eax708; X86-NEXT: subl %ecx, %eax709; X86-NEXT: sbbl %ecx, %edx710; X86-NEXT: retl711;712; X64-LABEL: abd_cmp_i64:713; X64: # %bb.0:714; X64-NEXT: movq %rdi, %rax715; X64-NEXT: subq %rsi, %rax716; X64-NEXT: subq %rdi, %rsi717; X64-NEXT: cmovaeq %rsi, %rax718; X64-NEXT: retq719 %cmp = icmp uge i64 %a, %b720 %ab = sub i64 %a, %b721 %ba = sub i64 %b, %a722 %sel = select i1 %cmp, i64 %ab, i64 %ba723 ret i64 %sel724}725 726define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {727; X86-LABEL: abd_cmp_i128:728; X86: # %bb.0:729; X86-NEXT: pushl %ebp730; X86-NEXT: movl %esp, %ebp731; X86-NEXT: pushl %edi732; X86-NEXT: pushl %esi733; X86-NEXT: andl $-16, %esp734; X86-NEXT: movl 32(%ebp), %edx735; X86-NEXT: movl 36(%ebp), %ecx736; X86-NEXT: movl 24(%ebp), %edi737; X86-NEXT: movl 28(%ebp), %esi738; X86-NEXT: xorl %eax, %eax739; X86-NEXT: subl 40(%ebp), %edi740; X86-NEXT: sbbl 44(%ebp), %esi741; X86-NEXT: sbbl 48(%ebp), %edx742; X86-NEXT: sbbl 52(%ebp), %ecx743; X86-NEXT: sbbl %eax, %eax744; X86-NEXT: xorl %eax, %ecx745; X86-NEXT: xorl %eax, %edx746; X86-NEXT: xorl %eax, %esi747; X86-NEXT: xorl %eax, %edi748; X86-NEXT: subl %eax, %edi749; X86-NEXT: sbbl %eax, %esi750; X86-NEXT: sbbl %eax, %edx751; X86-NEXT: sbbl %eax, %ecx752; X86-NEXT: movl 8(%ebp), %eax753; X86-NEXT: movl %edi, (%eax)754; X86-NEXT: movl %esi, 4(%eax)755; X86-NEXT: movl %edx, 8(%eax)756; X86-NEXT: movl %ecx, 12(%eax)757; X86-NEXT: leal -8(%ebp), %esp758; X86-NEXT: popl %esi759; X86-NEXT: popl %edi760; X86-NEXT: popl %ebp761; X86-NEXT: retl $4762;763; X64-LABEL: abd_cmp_i128:764; X64: # %bb.0:765; X64-NEXT: movq %rdi, %rax766; X64-NEXT: xorl %edi, %edi767; X64-NEXT: subq %rdx, %rax768; X64-NEXT: sbbq %rcx, %rsi769; X64-NEXT: sbbq %rdi, %rdi770; X64-NEXT: xorq %rdi, %rsi771; X64-NEXT: xorq %rdi, %rax772; X64-NEXT: subq %rdi, %rax773; X64-NEXT: sbbq %rdi, %rsi774; X64-NEXT: movq %rsi, %rdx775; X64-NEXT: retq776 %cmp = icmp uge i128 %a, %b777 %ab = sub i128 %a, %b778 %ba = sub i128 %b, %a779 %sel = select i1 %cmp, i128 %ab, i128 %ba780 ret i128 %sel781}782 783;784; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abdu(a,b)785;786 787define i8 @abd_select_i8(i8 %a, i8 %b) nounwind {788; X86-LABEL: abd_select_i8:789; X86: # %bb.0:790; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax791; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx792; X86-NEXT: movl %ecx, %edx793; X86-NEXT: subl %eax, %edx794; X86-NEXT: subl %ecx, %eax795; X86-NEXT: cmovbl %edx, %eax796; X86-NEXT: # kill: def $al killed $al killed $eax797; X86-NEXT: retl798;799; X64-LABEL: abd_select_i8:800; X64: # %bb.0:801; X64-NEXT: movzbl %sil, %eax802; X64-NEXT: movzbl %dil, %ecx803; X64-NEXT: movl %ecx, %edx804; X64-NEXT: subl %eax, %edx805; X64-NEXT: subl %ecx, %eax806; X64-NEXT: cmovbl %edx, %eax807; X64-NEXT: # kill: def $al killed $al killed $eax808; X64-NEXT: retq809 %cmp = icmp ult i8 %a, %b810 %ab = select i1 %cmp, i8 %a, i8 %b811 %ba = select i1 %cmp, i8 %b, i8 %a812 %sub = sub i8 %ba, %ab813 ret i8 %sub814}815 816define i16 @abd_select_i16(i16 %a, i16 %b) nounwind {817; X86-LABEL: abd_select_i16:818; X86: # %bb.0:819; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax820; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx821; X86-NEXT: movl %ecx, %edx822; X86-NEXT: subl %eax, %edx823; X86-NEXT: subl %ecx, %eax824; X86-NEXT: cmovbl %edx, %eax825; X86-NEXT: # kill: def $ax killed $ax killed $eax826; X86-NEXT: retl827;828; X64-LABEL: abd_select_i16:829; X64: # %bb.0:830; X64-NEXT: movzwl %si, %eax831; X64-NEXT: movzwl %di, %ecx832; X64-NEXT: movl %ecx, %edx833; X64-NEXT: subl %eax, %edx834; X64-NEXT: subl %ecx, %eax835; X64-NEXT: cmovbl %edx, %eax836; X64-NEXT: # kill: def $ax killed $ax killed $eax837; X64-NEXT: retq838 %cmp = icmp ule i16 %a, %b839 %ab = select i1 %cmp, i16 %a, i16 %b840 %ba = select i1 %cmp, i16 %b, i16 %a841 %sub = sub i16 %ba, %ab842 ret i16 %sub843}844 845define i32 @abd_select_i32(i32 %a, i32 %b) nounwind {846; X86-LABEL: abd_select_i32:847; X86: # %bb.0:848; X86-NEXT: movl {{[0-9]+}}(%esp), %eax849; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx850; X86-NEXT: movl %ecx, %edx851; X86-NEXT: subl %eax, %edx852; X86-NEXT: subl %ecx, %eax853; X86-NEXT: cmovbl %edx, %eax854; X86-NEXT: retl855;856; X64-LABEL: abd_select_i32:857; X64: # %bb.0:858; X64-NEXT: movl %edi, %eax859; X64-NEXT: subl %esi, %eax860; X64-NEXT: subl %edi, %esi861; X64-NEXT: cmovael %esi, %eax862; X64-NEXT: retq863 %cmp = icmp ugt i32 %a, %b864 %ab = select i1 %cmp, i32 %a, i32 %b865 %ba = select i1 %cmp, i32 %b, i32 %a866 %sub = sub i32 %ab, %ba867 ret i32 %sub868}869 870define i64 @abd_select_i64(i64 %a, i64 %b) nounwind {871; X86-LABEL: abd_select_i64:872; X86: # %bb.0:873; X86-NEXT: movl {{[0-9]+}}(%esp), %eax874; X86-NEXT: movl {{[0-9]+}}(%esp), %edx875; X86-NEXT: xorl %ecx, %ecx876; X86-NEXT: subl {{[0-9]+}}(%esp), %eax877; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx878; X86-NEXT: sbbl %ecx, %ecx879; X86-NEXT: xorl %ecx, %edx880; X86-NEXT: xorl %ecx, %eax881; X86-NEXT: subl %ecx, %eax882; X86-NEXT: sbbl %ecx, %edx883; X86-NEXT: retl884;885; X64-LABEL: abd_select_i64:886; X64: # %bb.0:887; X64-NEXT: movq %rdi, %rax888; X64-NEXT: subq %rsi, %rax889; X64-NEXT: subq %rdi, %rsi890; X64-NEXT: cmovaeq %rsi, %rax891; X64-NEXT: retq892 %cmp = icmp uge i64 %a, %b893 %ab = select i1 %cmp, i64 %a, i64 %b894 %ba = select i1 %cmp, i64 %b, i64 %a895 %sub = sub i64 %ab, %ba896 ret i64 %sub897}898 899define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {900; X86-LABEL: abd_select_i128:901; X86: # %bb.0:902; X86-NEXT: pushl %ebp903; X86-NEXT: movl %esp, %ebp904; X86-NEXT: pushl %edi905; X86-NEXT: pushl %esi906; X86-NEXT: andl $-16, %esp907; X86-NEXT: movl 32(%ebp), %edx908; X86-NEXT: movl 36(%ebp), %ecx909; X86-NEXT: movl 24(%ebp), %edi910; X86-NEXT: movl 28(%ebp), %esi911; X86-NEXT: xorl %eax, %eax912; X86-NEXT: subl 40(%ebp), %edi913; X86-NEXT: sbbl 44(%ebp), %esi914; X86-NEXT: sbbl 48(%ebp), %edx915; X86-NEXT: sbbl 52(%ebp), %ecx916; X86-NEXT: sbbl %eax, %eax917; X86-NEXT: xorl %eax, %ecx918; X86-NEXT: xorl %eax, %edx919; X86-NEXT: xorl %eax, %esi920; X86-NEXT: xorl %eax, %edi921; X86-NEXT: subl %eax, %edi922; X86-NEXT: sbbl %eax, %esi923; X86-NEXT: sbbl %eax, %edx924; X86-NEXT: sbbl %eax, %ecx925; X86-NEXT: movl 8(%ebp), %eax926; X86-NEXT: movl %edi, (%eax)927; X86-NEXT: movl %esi, 4(%eax)928; X86-NEXT: movl %edx, 8(%eax)929; X86-NEXT: movl %ecx, 12(%eax)930; X86-NEXT: leal -8(%ebp), %esp931; X86-NEXT: popl %esi932; X86-NEXT: popl %edi933; X86-NEXT: popl %ebp934; X86-NEXT: retl $4935;936; X64-LABEL: abd_select_i128:937; X64: # %bb.0:938; X64-NEXT: movq %rdi, %rax939; X64-NEXT: xorl %edi, %edi940; X64-NEXT: subq %rdx, %rax941; X64-NEXT: sbbq %rcx, %rsi942; X64-NEXT: sbbq %rdi, %rdi943; X64-NEXT: xorq %rdi, %rsi944; X64-NEXT: xorq %rdi, %rax945; X64-NEXT: subq %rdi, %rax946; X64-NEXT: sbbq %rdi, %rsi947; X64-NEXT: movq %rsi, %rdx948; X64-NEXT: retq949 %cmp = icmp ult i128 %a, %b950 %ab = select i1 %cmp, i128 %a, i128 %b951 %ba = select i1 %cmp, i128 %b, i128 %a952 %sub = sub i128 %ba, %ab953 ret i128 %sub954}955 956declare i8 @llvm.abs.i8(i8, i1)957declare i16 @llvm.abs.i16(i16, i1)958declare i32 @llvm.abs.i32(i32, i1)959declare i64 @llvm.abs.i64(i64, i1)960declare i128 @llvm.abs.i128(i128, i1)961 962declare i8 @llvm.umax.i8(i8, i8)963declare i16 @llvm.umax.i16(i16, i16)964declare i32 @llvm.umax.i32(i32, i32)965declare i64 @llvm.umax.i64(i64, i64)966 967declare i8 @llvm.umin.i8(i8, i8)968declare i16 @llvm.umin.i16(i16, i16)969declare i32 @llvm.umin.i32(i32, i32)970declare i64 @llvm.umin.i64(i64, i64)971