1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686 -mattr=cmov | FileCheck %s --check-prefixes=X86 3; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s --check-prefixes=X64 4 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), %eax 13; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 14; X86-NEXT: movl %ecx, %edx 15; X86-NEXT: subl %eax, %edx 16; X86-NEXT: subl %ecx, %eax 17; X86-NEXT: cmovll %edx, %eax 18; X86-NEXT: # kill: def $al killed $al killed $eax 19; X86-NEXT: retl 20; 21; X64-LABEL: abd_ext_i8: 22; X64: # %bb.0: 23; X64-NEXT: movsbl %sil, %eax 24; X64-NEXT: movsbl %dil, %ecx 25; X64-NEXT: movl %ecx, %edx 26; X64-NEXT: subl %eax, %edx 27; X64-NEXT: subl %ecx, %eax 28; X64-NEXT: cmovll %edx, %eax 29; X64-NEXT: # kill: def $al killed $al killed $eax 30; X64-NEXT: retq 31 %aext = sext i8 %a to i64 32 %bext = sext i8 %b to i64 33 %sub = sub i64 %aext, %bext 34 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 35 %trunc = trunc i64 %abs to i8 36 ret i8 %trunc 37} 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), %eax 43; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 44; X86-NEXT: movl %ecx, %edx 45; X86-NEXT: subl %eax, %edx 46; X86-NEXT: subl %ecx, %eax 47; X86-NEXT: cmovll %edx, %eax 48; X86-NEXT: # kill: def $al killed $al killed $eax 49; X86-NEXT: retl 50; 51; X64-LABEL: abd_ext_i8_i16: 52; X64: # %bb.0: 53; X64-NEXT: movsbl %dil, %ecx 54; X64-NEXT: subl %esi, %edi 55; X64-NEXT: movswl %si, %eax 56; X64-NEXT: subl %ecx, %eax 57; X64-NEXT: cmovll %edi, %eax 58; X64-NEXT: # kill: def $al killed $al killed $eax 59; X64-NEXT: retq 60 %aext = sext i8 %a to i64 61 %bext = sext i16 %b to i64 62 %sub = sub i64 %aext, %bext 63 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 64 %trunc = trunc i64 %abs to i8 65 ret i8 %trunc 66} 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), %eax 72; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 73; X86-NEXT: movl %ecx, %edx 74; X86-NEXT: subl %eax, %edx 75; X86-NEXT: subl %ecx, %eax 76; X86-NEXT: cmovll %edx, %eax 77; X86-NEXT: # kill: def $al killed $al killed $eax 78; X86-NEXT: retl 79; 80; X64-LABEL: abd_ext_i8_undef: 81; X64: # %bb.0: 82; X64-NEXT: movsbl %sil, %eax 83; X64-NEXT: movsbl %dil, %ecx 84; X64-NEXT: movl %ecx, %edx 85; X64-NEXT: subl %eax, %edx 86; X64-NEXT: subl %ecx, %eax 87; X64-NEXT: cmovll %edx, %eax 88; X64-NEXT: # kill: def $al killed $al killed $eax 89; X64-NEXT: retq 90 %aext = sext i8 %a to i64 91 %bext = sext i8 %b to i64 92 %sub = sub i64 %aext, %bext 93 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 94 %trunc = trunc i64 %abs to i8 95 ret i8 %trunc 96} 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), %eax 102; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 103; X86-NEXT: movl %ecx, %edx 104; X86-NEXT: subl %eax, %edx 105; X86-NEXT: subl %ecx, %eax 106; X86-NEXT: cmovll %edx, %eax 107; X86-NEXT: # kill: def $ax killed $ax killed $eax 108; X86-NEXT: retl 109; 110; X64-LABEL: abd_ext_i16: 111; X64: # %bb.0: 112; X64-NEXT: movswl %si, %eax 113; X64-NEXT: movswl %di, %ecx 114; X64-NEXT: movl %ecx, %edx 115; X64-NEXT: subl %eax, %edx 116; X64-NEXT: subl %ecx, %eax 117; X64-NEXT: cmovll %edx, %eax 118; X64-NEXT: # kill: def $ax killed $ax killed $eax 119; X64-NEXT: retq 120 %aext = sext i16 %a to i64 121 %bext = sext i16 %b to i64 122 %sub = sub i64 %aext, %bext 123 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 124 %trunc = trunc i64 %abs to i16 125 ret i16 %trunc 126} 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), %eax 132; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 133; X86-NEXT: movl %ecx, %edx 134; X86-NEXT: subl %eax, %edx 135; X86-NEXT: subl %ecx, %eax 136; X86-NEXT: cmovll %edx, %eax 137; X86-NEXT: # kill: def $ax killed $ax killed $eax 138; X86-NEXT: retl 139; 140; X64-LABEL: abd_ext_i16_i32: 141; X64: # %bb.0: 142; X64-NEXT: movswl %di, %ecx 143; X64-NEXT: movl %edi, %eax 144; X64-NEXT: subl %esi, %eax 145; X64-NEXT: subl %ecx, %esi 146; X64-NEXT: cmovgel %esi, %eax 147; X64-NEXT: # kill: def $ax killed $ax killed $eax 148; X64-NEXT: retq 149 %aext = sext i16 %a to i64 150 %bext = sext i32 %b to i64 151 %sub = sub i64 %aext, %bext 152 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 153 %trunc = trunc i64 %abs to i16 154 ret i16 %trunc 155} 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), %eax 161; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 162; X86-NEXT: movl %ecx, %edx 163; X86-NEXT: subl %eax, %edx 164; X86-NEXT: subl %ecx, %eax 165; X86-NEXT: cmovll %edx, %eax 166; X86-NEXT: # kill: def $ax killed $ax killed $eax 167; X86-NEXT: retl 168; 169; X64-LABEL: abd_ext_i16_undef: 170; X64: # %bb.0: 171; X64-NEXT: movswl %si, %eax 172; X64-NEXT: movswl %di, %ecx 173; X64-NEXT: movl %ecx, %edx 174; X64-NEXT: subl %eax, %edx 175; X64-NEXT: subl %ecx, %eax 176; X64-NEXT: cmovll %edx, %eax 177; X64-NEXT: # kill: def $ax killed $ax killed $eax 178; X64-NEXT: retq 179 %aext = sext i16 %a to i64 180 %bext = sext i16 %b to i64 181 %sub = sub i64 %aext, %bext 182 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 183 %trunc = trunc i64 %abs to i16 184 ret i16 %trunc 185} 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), %eax 191; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 192; X86-NEXT: movl %ecx, %edx 193; X86-NEXT: subl %eax, %edx 194; X86-NEXT: subl %ecx, %eax 195; X86-NEXT: cmovll %edx, %eax 196; X86-NEXT: retl 197; 198; X64-LABEL: abd_ext_i32: 199; X64: # %bb.0: 200; X64-NEXT: movl %edi, %eax 201; X64-NEXT: subl %esi, %eax 202; X64-NEXT: subl %edi, %esi 203; X64-NEXT: cmovgel %esi, %eax 204; X64-NEXT: retq 205 %aext = sext i32 %a to i64 206 %bext = sext i32 %b to i64 207 %sub = sub i64 %aext, %bext 208 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 209 %trunc = trunc i64 %abs to i32 210 ret i32 %trunc 211} 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), %eax 217; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 218; X86-NEXT: movl %ecx, %edx 219; X86-NEXT: subl %eax, %edx 220; X86-NEXT: subl %ecx, %eax 221; X86-NEXT: cmovll %edx, %eax 222; X86-NEXT: retl 223; 224; X64-LABEL: abd_ext_i32_i16: 225; X64: # %bb.0: 226; X64-NEXT: movswl %si, %eax 227; X64-NEXT: movl %edi, %ecx 228; X64-NEXT: subl %eax, %ecx 229; X64-NEXT: subl %edi, %eax 230; X64-NEXT: cmovll %ecx, %eax 231; X64-NEXT: retq 232 %aext = sext i32 %a to i64 233 %bext = sext i16 %b to i64 234 %sub = sub i64 %aext, %bext 235 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 236 %trunc = trunc i64 %abs to i32 237 ret i32 %trunc 238} 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), %eax 244; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 245; X86-NEXT: movl %ecx, %edx 246; X86-NEXT: subl %eax, %edx 247; X86-NEXT: subl %ecx, %eax 248; X86-NEXT: cmovll %edx, %eax 249; X86-NEXT: retl 250; 251; X64-LABEL: abd_ext_i32_undef: 252; X64: # %bb.0: 253; X64-NEXT: movl %edi, %eax 254; X64-NEXT: subl %esi, %eax 255; X64-NEXT: subl %edi, %esi 256; X64-NEXT: cmovgel %esi, %eax 257; X64-NEXT: retq 258 %aext = sext i32 %a to i64 259 %bext = sext i32 %b to i64 260 %sub = sub i64 %aext, %bext 261 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 262 %trunc = trunc i64 %abs to i32 263 ret i32 %trunc 264} 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 %ebx 270; X86-NEXT: pushl %edi 271; X86-NEXT: pushl %esi 272; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 273; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 274; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 275; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 276; X86-NEXT: movl %ecx, %edi 277; X86-NEXT: subl %eax, %edi 278; X86-NEXT: movl %esi, %ebx 279; X86-NEXT: sbbl %edx, %ebx 280; X86-NEXT: subl %ecx, %eax 281; X86-NEXT: sbbl %esi, %edx 282; X86-NEXT: cmovll %edi, %eax 283; X86-NEXT: cmovll %ebx, %edx 284; X86-NEXT: popl %esi 285; X86-NEXT: popl %edi 286; X86-NEXT: popl %ebx 287; X86-NEXT: retl 288; 289; X64-LABEL: abd_ext_i64: 290; X64: # %bb.0: 291; X64-NEXT: movq %rdi, %rax 292; X64-NEXT: subq %rsi, %rax 293; X64-NEXT: subq %rdi, %rsi 294; X64-NEXT: cmovgeq %rsi, %rax 295; X64-NEXT: retq 296 %aext = sext i64 %a to i128 297 %bext = sext i64 %b to i128 298 %sub = sub i128 %aext, %bext 299 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false) 300 %trunc = trunc i128 %abs to i64 301 ret i64 %trunc 302} 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 %ebx 308; X86-NEXT: pushl %edi 309; X86-NEXT: pushl %esi 310; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 311; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 312; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 313; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 314; X86-NEXT: movl %ecx, %edi 315; X86-NEXT: subl %eax, %edi 316; X86-NEXT: movl %esi, %ebx 317; X86-NEXT: sbbl %edx, %ebx 318; X86-NEXT: subl %ecx, %eax 319; X86-NEXT: sbbl %esi, %edx 320; X86-NEXT: cmovll %edi, %eax 321; X86-NEXT: cmovll %ebx, %edx 322; X86-NEXT: popl %esi 323; X86-NEXT: popl %edi 324; X86-NEXT: popl %ebx 325; X86-NEXT: retl 326; 327; X64-LABEL: abd_ext_i64_undef: 328; X64: # %bb.0: 329; X64-NEXT: movq %rdi, %rax 330; X64-NEXT: subq %rsi, %rax 331; X64-NEXT: subq %rdi, %rsi 332; X64-NEXT: cmovgeq %rsi, %rax 333; X64-NEXT: retq 334 %aext = sext i64 %a to i128 335 %bext = sext i64 %b to i128 336 %sub = sub i128 %aext, %bext 337 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true) 338 %trunc = trunc i128 %abs to i64 339 ret i64 %trunc 340} 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 %ebp 346; X86-NEXT: pushl %ebx 347; X86-NEXT: pushl %edi 348; X86-NEXT: pushl %esi 349; X86-NEXT: pushl %eax 350; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 351; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 352; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 353; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 354; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 355; X86-NEXT: subl %edx, %eax 356; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 357; X86-NEXT: sbbl %esi, %ebx 358; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 359; X86-NEXT: sbbl %ecx, %ebp 360; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 361; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 362; X86-NEXT: sbbl %edi, %eax 363; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 364; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 365; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 366; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi 367; X86-NEXT: cmovll (%esp), %edx # 4-byte Folded Reload 368; X86-NEXT: cmovll %ebx, %esi 369; X86-NEXT: cmovll %ebp, %ecx 370; X86-NEXT: cmovll %eax, %edi 371; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 372; X86-NEXT: movl %edi, 12(%eax) 373; X86-NEXT: movl %ecx, 8(%eax) 374; X86-NEXT: movl %esi, 4(%eax) 375; X86-NEXT: movl %edx, (%eax) 376; X86-NEXT: addl $4, %esp 377; X86-NEXT: popl %esi 378; X86-NEXT: popl %edi 379; X86-NEXT: popl %ebx 380; X86-NEXT: popl %ebp 381; X86-NEXT: retl $4 382; 383; X64-LABEL: abd_ext_i128: 384; X64: # %bb.0: 385; X64-NEXT: movq %rdi, %rax 386; X64-NEXT: subq %rdx, %rax 387; X64-NEXT: movq %rsi, %r8 388; X64-NEXT: sbbq %rcx, %r8 389; X64-NEXT: subq %rdi, %rdx 390; X64-NEXT: sbbq %rsi, %rcx 391; X64-NEXT: cmovgeq %rdx, %rax 392; X64-NEXT: cmovgeq %rcx, %r8 393; X64-NEXT: movq %r8, %rdx 394; X64-NEXT: retq 395 %aext = sext i128 %a to i256 396 %bext = sext i128 %b to i256 397 %sub = sub i256 %aext, %bext 398 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false) 399 %trunc = trunc i256 %abs to i128 400 ret i128 %trunc 401} 402 403define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind { 404; X86-LABEL: abd_ext_i128_undef: 405; X86: # %bb.0: 406; X86-NEXT: pushl %ebp 407; X86-NEXT: pushl %ebx 408; X86-NEXT: pushl %edi 409; X86-NEXT: pushl %esi 410; X86-NEXT: pushl %eax 411; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 412; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 413; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 414; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 415; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 416; X86-NEXT: subl %edx, %eax 417; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 418; X86-NEXT: sbbl %esi, %ebx 419; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 420; X86-NEXT: sbbl %ecx, %ebp 421; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 422; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 423; X86-NEXT: sbbl %edi, %eax 424; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 425; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 426; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 427; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi 428; X86-NEXT: cmovll (%esp), %edx # 4-byte Folded Reload 429; X86-NEXT: cmovll %ebx, %esi 430; X86-NEXT: cmovll %ebp, %ecx 431; X86-NEXT: cmovll %eax, %edi 432; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 433; X86-NEXT: movl %edi, 12(%eax) 434; X86-NEXT: movl %ecx, 8(%eax) 435; X86-NEXT: movl %esi, 4(%eax) 436; X86-NEXT: movl %edx, (%eax) 437; X86-NEXT: addl $4, %esp 438; X86-NEXT: popl %esi 439; X86-NEXT: popl %edi 440; X86-NEXT: popl %ebx 441; X86-NEXT: popl %ebp 442; X86-NEXT: retl $4 443; 444; X64-LABEL: abd_ext_i128_undef: 445; X64: # %bb.0: 446; X64-NEXT: movq %rdi, %rax 447; X64-NEXT: subq %rdx, %rax 448; X64-NEXT: movq %rsi, %r8 449; X64-NEXT: sbbq %rcx, %r8 450; X64-NEXT: subq %rdi, %rdx 451; X64-NEXT: sbbq %rsi, %rcx 452; X64-NEXT: cmovgeq %rdx, %rax 453; X64-NEXT: cmovgeq %rcx, %r8 454; X64-NEXT: movq %r8, %rdx 455; X64-NEXT: retq 456 %aext = sext i128 %a to i256 457 %bext = sext i128 %b to i256 458 %sub = sub i256 %aext, %bext 459 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true) 460 %trunc = trunc i256 %abs to i128 461 ret i128 %trunc 462} 463 464; 465; sub(smax(a,b),smin(a,b)) -> abds(a,b) 466; 467 468define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind { 469; X86-LABEL: abd_minmax_i8: 470; X86: # %bb.0: 471; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 472; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 473; X86-NEXT: movl %ecx, %edx 474; X86-NEXT: subl %eax, %edx 475; X86-NEXT: subl %ecx, %eax 476; X86-NEXT: cmovll %edx, %eax 477; X86-NEXT: # kill: def $al killed $al killed $eax 478; X86-NEXT: retl 479; 480; X64-LABEL: abd_minmax_i8: 481; X64: # %bb.0: 482; X64-NEXT: movsbl %sil, %eax 483; X64-NEXT: movsbl %dil, %ecx 484; X64-NEXT: movl %ecx, %edx 485; X64-NEXT: subl %eax, %edx 486; X64-NEXT: subl %ecx, %eax 487; X64-NEXT: cmovll %edx, %eax 488; X64-NEXT: # kill: def $al killed $al killed $eax 489; X64-NEXT: retq 490 %min = call i8 @llvm.smin.i8(i8 %a, i8 %b) 491 %max = call i8 @llvm.smax.i8(i8 %a, i8 %b) 492 %sub = sub i8 %max, %min 493 ret i8 %sub 494} 495 496define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind { 497; X86-LABEL: abd_minmax_i16: 498; X86: # %bb.0: 499; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax 500; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 501; X86-NEXT: movl %ecx, %edx 502; X86-NEXT: subl %eax, %edx 503; X86-NEXT: subl %ecx, %eax 504; X86-NEXT: cmovll %edx, %eax 505; X86-NEXT: # kill: def $ax killed $ax killed $eax 506; X86-NEXT: retl 507; 508; X64-LABEL: abd_minmax_i16: 509; X64: # %bb.0: 510; X64-NEXT: movswl %si, %eax 511; X64-NEXT: movswl %di, %ecx 512; X64-NEXT: movl %ecx, %edx 513; X64-NEXT: subl %eax, %edx 514; X64-NEXT: subl %ecx, %eax 515; X64-NEXT: cmovll %edx, %eax 516; X64-NEXT: # kill: def $ax killed $ax killed $eax 517; X64-NEXT: retq 518 %min = call i16 @llvm.smin.i16(i16 %a, i16 %b) 519 %max = call i16 @llvm.smax.i16(i16 %a, i16 %b) 520 %sub = sub i16 %max, %min 521 ret i16 %sub 522} 523 524define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind { 525; X86-LABEL: abd_minmax_i32: 526; X86: # %bb.0: 527; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 528; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 529; X86-NEXT: movl %ecx, %edx 530; X86-NEXT: subl %eax, %edx 531; X86-NEXT: subl %ecx, %eax 532; X86-NEXT: cmovll %edx, %eax 533; X86-NEXT: retl 534; 535; X64-LABEL: abd_minmax_i32: 536; X64: # %bb.0: 537; X64-NEXT: movl %edi, %eax 538; X64-NEXT: subl %esi, %eax 539; X64-NEXT: subl %edi, %esi 540; X64-NEXT: cmovgel %esi, %eax 541; X64-NEXT: retq 542 %min = call i32 @llvm.smin.i32(i32 %a, i32 %b) 543 %max = call i32 @llvm.smax.i32(i32 %a, i32 %b) 544 %sub = sub i32 %max, %min 545 ret i32 %sub 546} 547 548define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind { 549; X86-LABEL: abd_minmax_i64: 550; X86: # %bb.0: 551; X86-NEXT: pushl %ebx 552; X86-NEXT: pushl %edi 553; X86-NEXT: pushl %esi 554; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 555; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 556; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 557; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 558; X86-NEXT: movl %ecx, %edi 559; X86-NEXT: subl %eax, %edi 560; X86-NEXT: movl %esi, %ebx 561; X86-NEXT: sbbl %edx, %ebx 562; X86-NEXT: subl %ecx, %eax 563; X86-NEXT: sbbl %esi, %edx 564; X86-NEXT: cmovll %edi, %eax 565; X86-NEXT: cmovll %ebx, %edx 566; X86-NEXT: popl %esi 567; X86-NEXT: popl %edi 568; X86-NEXT: popl %ebx 569; X86-NEXT: retl 570; 571; X64-LABEL: abd_minmax_i64: 572; X64: # %bb.0: 573; X64-NEXT: movq %rdi, %rax 574; X64-NEXT: subq %rsi, %rax 575; X64-NEXT: subq %rdi, %rsi 576; X64-NEXT: cmovgeq %rsi, %rax 577; X64-NEXT: retq 578 %min = call i64 @llvm.smin.i64(i64 %a, i64 %b) 579 %max = call i64 @llvm.smax.i64(i64 %a, i64 %b) 580 %sub = sub i64 %max, %min 581 ret i64 %sub 582} 583 584define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind { 585; X86-LABEL: abd_minmax_i128: 586; X86: # %bb.0: 587; X86-NEXT: pushl %ebp 588; X86-NEXT: pushl %ebx 589; X86-NEXT: pushl %edi 590; X86-NEXT: pushl %esi 591; X86-NEXT: pushl %eax 592; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 593; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 594; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 595; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 596; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 597; X86-NEXT: subl %edx, %eax 598; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 599; X86-NEXT: sbbl %esi, %ebx 600; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 601; X86-NEXT: sbbl %ecx, %ebp 602; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 603; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 604; X86-NEXT: sbbl %edi, %eax 605; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 606; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 607; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 608; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi 609; X86-NEXT: cmovll (%esp), %edx # 4-byte Folded Reload 610; X86-NEXT: cmovll %ebx, %esi 611; X86-NEXT: cmovll %ebp, %ecx 612; X86-NEXT: cmovll %eax, %edi 613; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 614; X86-NEXT: movl %edi, 12(%eax) 615; X86-NEXT: movl %ecx, 8(%eax) 616; X86-NEXT: movl %esi, 4(%eax) 617; X86-NEXT: movl %edx, (%eax) 618; X86-NEXT: addl $4, %esp 619; X86-NEXT: popl %esi 620; X86-NEXT: popl %edi 621; X86-NEXT: popl %ebx 622; X86-NEXT: popl %ebp 623; X86-NEXT: retl $4 624; 625; X64-LABEL: abd_minmax_i128: 626; X64: # %bb.0: 627; X64-NEXT: movq %rdi, %rax 628; X64-NEXT: subq %rdx, %rax 629; X64-NEXT: movq %rsi, %r8 630; X64-NEXT: sbbq %rcx, %r8 631; X64-NEXT: subq %rdi, %rdx 632; X64-NEXT: sbbq %rsi, %rcx 633; X64-NEXT: cmovgeq %rdx, %rax 634; X64-NEXT: cmovgeq %rcx, %r8 635; X64-NEXT: movq %r8, %rdx 636; X64-NEXT: retq 637 %min = call i128 @llvm.smin.i128(i128 %a, i128 %b) 638 %max = call i128 @llvm.smax.i128(i128 %a, i128 %b) 639 %sub = sub i128 %max, %min 640 ret i128 %sub 641} 642 643; 644; select(icmp(a,b),sub(a,b),sub(b,a)) -> abds(a,b) 645; 646 647define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind { 648; X86-LABEL: abd_cmp_i8: 649; X86: # %bb.0: 650; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 651; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 652; X86-NEXT: movl %ecx, %edx 653; X86-NEXT: subl %eax, %edx 654; X86-NEXT: subl %ecx, %eax 655; X86-NEXT: cmovll %edx, %eax 656; X86-NEXT: # kill: def $al killed $al killed $eax 657; X86-NEXT: retl 658; 659; X64-LABEL: abd_cmp_i8: 660; X64: # %bb.0: 661; X64-NEXT: movsbl %sil, %eax 662; X64-NEXT: movsbl %dil, %ecx 663; X64-NEXT: movl %ecx, %edx 664; X64-NEXT: subl %eax, %edx 665; X64-NEXT: subl %ecx, %eax 666; X64-NEXT: cmovll %edx, %eax 667; X64-NEXT: # kill: def $al killed $al killed $eax 668; X64-NEXT: retq 669 %cmp = icmp sgt i8 %a, %b 670 %ab = sub i8 %a, %b 671 %ba = sub i8 %b, %a 672 %sel = select i1 %cmp, i8 %ab, i8 %ba 673 ret i8 %sel 674} 675 676define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind { 677; X86-LABEL: abd_cmp_i16: 678; X86: # %bb.0: 679; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax 680; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 681; X86-NEXT: movl %ecx, %edx 682; X86-NEXT: subl %eax, %edx 683; X86-NEXT: subl %ecx, %eax 684; X86-NEXT: cmovll %edx, %eax 685; X86-NEXT: # kill: def $ax killed $ax killed $eax 686; X86-NEXT: retl 687; 688; X64-LABEL: abd_cmp_i16: 689; X64: # %bb.0: 690; X64-NEXT: movswl %si, %eax 691; X64-NEXT: movswl %di, %ecx 692; X64-NEXT: movl %ecx, %edx 693; X64-NEXT: subl %eax, %edx 694; X64-NEXT: subl %ecx, %eax 695; X64-NEXT: cmovll %edx, %eax 696; X64-NEXT: # kill: def $ax killed $ax killed $eax 697; X64-NEXT: retq 698 %cmp = icmp sge i16 %a, %b 699 %ab = sub i16 %a, %b 700 %ba = sub i16 %b, %a 701 %sel = select i1 %cmp, i16 %ab, i16 %ba 702 ret i16 %sel 703} 704 705define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind { 706; X86-LABEL: abd_cmp_i32: 707; X86: # %bb.0: 708; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 709; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 710; X86-NEXT: movl %ecx, %edx 711; X86-NEXT: subl %eax, %edx 712; X86-NEXT: subl %ecx, %eax 713; X86-NEXT: cmovll %edx, %eax 714; X86-NEXT: retl 715; 716; X64-LABEL: abd_cmp_i32: 717; X64: # %bb.0: 718; X64-NEXT: movl %edi, %eax 719; X64-NEXT: subl %esi, %eax 720; X64-NEXT: subl %edi, %esi 721; X64-NEXT: cmovgel %esi, %eax 722; X64-NEXT: retq 723 %cmp = icmp slt i32 %a, %b 724 %ab = sub i32 %a, %b 725 %ba = sub i32 %b, %a 726 %sel = select i1 %cmp, i32 %ba, i32 %ab 727 ret i32 %sel 728} 729 730define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind { 731; X86-LABEL: abd_cmp_i64: 732; X86: # %bb.0: 733; X86-NEXT: pushl %ebx 734; X86-NEXT: pushl %edi 735; X86-NEXT: pushl %esi 736; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 737; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 738; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 739; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 740; X86-NEXT: movl %ecx, %edi 741; X86-NEXT: subl %eax, %edi 742; X86-NEXT: movl %esi, %ebx 743; X86-NEXT: sbbl %edx, %ebx 744; X86-NEXT: subl %ecx, %eax 745; X86-NEXT: sbbl %esi, %edx 746; X86-NEXT: cmovll %edi, %eax 747; X86-NEXT: cmovll %ebx, %edx 748; X86-NEXT: popl %esi 749; X86-NEXT: popl %edi 750; X86-NEXT: popl %ebx 751; X86-NEXT: retl 752; 753; X64-LABEL: abd_cmp_i64: 754; X64: # %bb.0: 755; X64-NEXT: movq %rdi, %rax 756; X64-NEXT: subq %rsi, %rax 757; X64-NEXT: subq %rdi, %rsi 758; X64-NEXT: cmovgeq %rsi, %rax 759; X64-NEXT: retq 760 %cmp = icmp sge i64 %a, %b 761 %ab = sub i64 %a, %b 762 %ba = sub i64 %b, %a 763 %sel = select i1 %cmp, i64 %ab, i64 %ba 764 ret i64 %sel 765} 766 767define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind { 768; X86-LABEL: abd_cmp_i128: 769; X86: # %bb.0: 770; X86-NEXT: pushl %ebp 771; X86-NEXT: pushl %ebx 772; X86-NEXT: pushl %edi 773; X86-NEXT: pushl %esi 774; X86-NEXT: pushl %eax 775; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 776; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 777; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 778; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 779; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 780; X86-NEXT: subl %edx, %eax 781; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 782; X86-NEXT: sbbl %esi, %ebx 783; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 784; X86-NEXT: sbbl %ecx, %ebp 785; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 786; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 787; X86-NEXT: sbbl %edi, %eax 788; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 789; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 790; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 791; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi 792; X86-NEXT: cmovll (%esp), %edx # 4-byte Folded Reload 793; X86-NEXT: cmovll %ebx, %esi 794; X86-NEXT: cmovll %ebp, %ecx 795; X86-NEXT: cmovll %eax, %edi 796; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 797; X86-NEXT: movl %edi, 12(%eax) 798; X86-NEXT: movl %ecx, 8(%eax) 799; X86-NEXT: movl %esi, 4(%eax) 800; X86-NEXT: movl %edx, (%eax) 801; X86-NEXT: addl $4, %esp 802; X86-NEXT: popl %esi 803; X86-NEXT: popl %edi 804; X86-NEXT: popl %ebx 805; X86-NEXT: popl %ebp 806; X86-NEXT: retl $4 807; 808; X64-LABEL: abd_cmp_i128: 809; X64: # %bb.0: 810; X64-NEXT: movq %rdi, %rax 811; X64-NEXT: subq %rdx, %rax 812; X64-NEXT: movq %rsi, %r8 813; X64-NEXT: sbbq %rcx, %r8 814; X64-NEXT: subq %rdi, %rdx 815; X64-NEXT: sbbq %rsi, %rcx 816; X64-NEXT: cmovgeq %rdx, %rax 817; X64-NEXT: cmovgeq %rcx, %r8 818; X64-NEXT: movq %r8, %rdx 819; X64-NEXT: retq 820 %cmp = icmp sge i128 %a, %b 821 %ab = sub i128 %a, %b 822 %ba = sub i128 %b, %a 823 %sel = select i1 %cmp, i128 %ab, i128 %ba 824 ret i128 %sel 825} 826 827; 828; abs(sub_nsw(x, y)) -> abds(a,b) 829; 830 831define i8 @abd_subnsw_i8(i8 %a, i8 %b) nounwind { 832; X86-LABEL: abd_subnsw_i8: 833; X86: # %bb.0: 834; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 835; X86-NEXT: subb {{[0-9]+}}(%esp), %al 836; X86-NEXT: movl %eax, %ecx 837; X86-NEXT: sarb $7, %cl 838; X86-NEXT: xorb %cl, %al 839; X86-NEXT: subb %cl, %al 840; X86-NEXT: retl 841; 842; X64-LABEL: abd_subnsw_i8: 843; X64: # %bb.0: 844; X64-NEXT: movl %edi, %eax 845; X64-NEXT: subb %sil, %al 846; X64-NEXT: movl %eax, %ecx 847; X64-NEXT: sarb $7, %cl 848; X64-NEXT: xorb %cl, %al 849; X64-NEXT: subb %cl, %al 850; X64-NEXT: # kill: def $al killed $al killed $eax 851; X64-NEXT: retq 852 %sub = sub nsw i8 %a, %b 853 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 false) 854 ret i8 %abs 855} 856 857define i8 @abd_subnsw_i8_undef(i8 %a, i8 %b) nounwind { 858; X86-LABEL: abd_subnsw_i8_undef: 859; X86: # %bb.0: 860; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 861; X86-NEXT: subb {{[0-9]+}}(%esp), %al 862; X86-NEXT: movl %eax, %ecx 863; X86-NEXT: sarb $7, %cl 864; X86-NEXT: xorb %cl, %al 865; X86-NEXT: subb %cl, %al 866; X86-NEXT: retl 867; 868; X64-LABEL: abd_subnsw_i8_undef: 869; X64: # %bb.0: 870; X64-NEXT: movl %edi, %eax 871; X64-NEXT: subb %sil, %al 872; X64-NEXT: movl %eax, %ecx 873; X64-NEXT: sarb $7, %cl 874; X64-NEXT: xorb %cl, %al 875; X64-NEXT: subb %cl, %al 876; X64-NEXT: # kill: def $al killed $al killed $eax 877; X64-NEXT: retq 878 %sub = sub nsw i8 %a, %b 879 %abs = call i8 @llvm.abs.i8(i8 %sub, i1 true) 880 ret i8 %abs 881} 882 883define i16 @abd_subnsw_i16(i16 %a, i16 %b) nounwind { 884; X86-LABEL: abd_subnsw_i16: 885; X86: # %bb.0: 886; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 887; X86-NEXT: subw {{[0-9]+}}(%esp), %cx 888; X86-NEXT: movl %ecx, %eax 889; X86-NEXT: negw %ax 890; X86-NEXT: cmovsw %cx, %ax 891; X86-NEXT: retl 892; 893; X64-LABEL: abd_subnsw_i16: 894; X64: # %bb.0: 895; X64-NEXT: subl %esi, %edi 896; X64-NEXT: movl %edi, %eax 897; X64-NEXT: negw %ax 898; X64-NEXT: cmovsw %di, %ax 899; X64-NEXT: retq 900 %sub = sub nsw i16 %a, %b 901 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 false) 902 ret i16 %abs 903} 904 905define i16 @abd_subnsw_i16_undef(i16 %a, i16 %b) nounwind { 906; X86-LABEL: abd_subnsw_i16_undef: 907; X86: # %bb.0: 908; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 909; X86-NEXT: subw {{[0-9]+}}(%esp), %cx 910; X86-NEXT: movl %ecx, %eax 911; X86-NEXT: negw %ax 912; X86-NEXT: cmovsw %cx, %ax 913; X86-NEXT: retl 914; 915; X64-LABEL: abd_subnsw_i16_undef: 916; X64: # %bb.0: 917; X64-NEXT: subl %esi, %edi 918; X64-NEXT: movl %edi, %eax 919; X64-NEXT: negw %ax 920; X64-NEXT: cmovsw %di, %ax 921; X64-NEXT: retq 922 %sub = sub nsw i16 %a, %b 923 %abs = call i16 @llvm.abs.i16(i16 %sub, i1 true) 924 ret i16 %abs 925} 926 927define i32 @abd_subnsw_i32(i32 %a, i32 %b) nounwind { 928; X86-LABEL: abd_subnsw_i32: 929; X86: # %bb.0: 930; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 931; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 932; X86-NEXT: movl %ecx, %edx 933; X86-NEXT: subl %eax, %edx 934; X86-NEXT: subl %ecx, %eax 935; X86-NEXT: cmovll %edx, %eax 936; X86-NEXT: retl 937; 938; X64-LABEL: abd_subnsw_i32: 939; X64: # %bb.0: 940; X64-NEXT: movl %edi, %eax 941; X64-NEXT: subl %esi, %eax 942; X64-NEXT: subl %edi, %esi 943; X64-NEXT: cmovgel %esi, %eax 944; X64-NEXT: retq 945 %sub = sub nsw i32 %a, %b 946 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false) 947 ret i32 %abs 948} 949 950define i32 @abd_subnsw_i32_undef(i32 %a, i32 %b) nounwind { 951; X86-LABEL: abd_subnsw_i32_undef: 952; X86: # %bb.0: 953; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 954; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 955; X86-NEXT: movl %ecx, %edx 956; X86-NEXT: subl %eax, %edx 957; X86-NEXT: subl %ecx, %eax 958; X86-NEXT: cmovll %edx, %eax 959; X86-NEXT: retl 960; 961; X64-LABEL: abd_subnsw_i32_undef: 962; X64: # %bb.0: 963; X64-NEXT: movl %edi, %eax 964; X64-NEXT: subl %esi, %eax 965; X64-NEXT: subl %edi, %esi 966; X64-NEXT: cmovgel %esi, %eax 967; X64-NEXT: retq 968 %sub = sub nsw i32 %a, %b 969 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 true) 970 ret i32 %abs 971} 972 973define i64 @abd_subnsw_i64(i64 %a, i64 %b) nounwind { 974; X86-LABEL: abd_subnsw_i64: 975; X86: # %bb.0: 976; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 977; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 978; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 979; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 980; X86-NEXT: movl %edx, %ecx 981; X86-NEXT: sarl $31, %ecx 982; X86-NEXT: xorl %ecx, %edx 983; X86-NEXT: xorl %ecx, %eax 984; X86-NEXT: subl %ecx, %eax 985; X86-NEXT: sbbl %ecx, %edx 986; X86-NEXT: retl 987; 988; X64-LABEL: abd_subnsw_i64: 989; X64: # %bb.0: 990; X64-NEXT: movq %rdi, %rax 991; X64-NEXT: subq %rsi, %rax 992; X64-NEXT: subq %rdi, %rsi 993; X64-NEXT: cmovgeq %rsi, %rax 994; X64-NEXT: retq 995 %sub = sub nsw i64 %a, %b 996 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 997 ret i64 %abs 998} 999 1000define i64 @abd_subnsw_i64_undef(i64 %a, i64 %b) nounwind { 1001; X86-LABEL: abd_subnsw_i64_undef: 1002; X86: # %bb.0: 1003; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1004; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1005; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 1006; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 1007; X86-NEXT: movl %edx, %ecx 1008; X86-NEXT: sarl $31, %ecx 1009; X86-NEXT: xorl %ecx, %edx 1010; X86-NEXT: xorl %ecx, %eax 1011; X86-NEXT: subl %ecx, %eax 1012; X86-NEXT: sbbl %ecx, %edx 1013; X86-NEXT: retl 1014; 1015; X64-LABEL: abd_subnsw_i64_undef: 1016; X64: # %bb.0: 1017; X64-NEXT: movq %rdi, %rax 1018; X64-NEXT: subq %rsi, %rax 1019; X64-NEXT: subq %rdi, %rsi 1020; X64-NEXT: cmovgeq %rsi, %rax 1021; X64-NEXT: retq 1022 %sub = sub nsw i64 %a, %b 1023 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 1024 ret i64 %abs 1025} 1026 1027define i128 @abd_subnsw_i128(i128 %a, i128 %b) nounwind { 1028; X86-LABEL: abd_subnsw_i128: 1029; X86: # %bb.0: 1030; X86-NEXT: pushl %ebx 1031; X86-NEXT: pushl %edi 1032; X86-NEXT: pushl %esi 1033; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1034; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1035; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1036; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 1037; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1038; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 1039; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 1040; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 1041; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 1042; X86-NEXT: movl %ecx, %ebx 1043; X86-NEXT: sarl $31, %ebx 1044; X86-NEXT: xorl %ebx, %ecx 1045; X86-NEXT: xorl %ebx, %edx 1046; X86-NEXT: xorl %ebx, %esi 1047; X86-NEXT: xorl %ebx, %edi 1048; X86-NEXT: subl %ebx, %edi 1049; X86-NEXT: sbbl %ebx, %esi 1050; X86-NEXT: sbbl %ebx, %edx 1051; X86-NEXT: sbbl %ebx, %ecx 1052; X86-NEXT: movl %edi, (%eax) 1053; X86-NEXT: movl %esi, 4(%eax) 1054; X86-NEXT: movl %edx, 8(%eax) 1055; X86-NEXT: movl %ecx, 12(%eax) 1056; X86-NEXT: popl %esi 1057; X86-NEXT: popl %edi 1058; X86-NEXT: popl %ebx 1059; X86-NEXT: retl $4 1060; 1061; X64-LABEL: abd_subnsw_i128: 1062; X64: # %bb.0: 1063; X64-NEXT: movq %rdi, %rax 1064; X64-NEXT: subq %rdx, %rax 1065; X64-NEXT: sbbq %rcx, %rsi 1066; X64-NEXT: movq %rsi, %rcx 1067; X64-NEXT: sarq $63, %rcx 1068; X64-NEXT: xorq %rcx, %rsi 1069; X64-NEXT: xorq %rcx, %rax 1070; X64-NEXT: subq %rcx, %rax 1071; X64-NEXT: sbbq %rcx, %rsi 1072; X64-NEXT: movq %rsi, %rdx 1073; X64-NEXT: retq 1074 %sub = sub nsw i128 %a, %b 1075 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false) 1076 ret i128 %abs 1077} 1078 1079define i128 @abd_subnsw_i128_undef(i128 %a, i128 %b) nounwind { 1080; X86-LABEL: abd_subnsw_i128_undef: 1081; X86: # %bb.0: 1082; X86-NEXT: pushl %ebx 1083; X86-NEXT: pushl %edi 1084; X86-NEXT: pushl %esi 1085; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1086; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1087; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1088; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 1089; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1090; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 1091; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 1092; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 1093; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 1094; X86-NEXT: movl %ecx, %ebx 1095; X86-NEXT: sarl $31, %ebx 1096; X86-NEXT: xorl %ebx, %ecx 1097; X86-NEXT: xorl %ebx, %edx 1098; X86-NEXT: xorl %ebx, %esi 1099; X86-NEXT: xorl %ebx, %edi 1100; X86-NEXT: subl %ebx, %edi 1101; X86-NEXT: sbbl %ebx, %esi 1102; X86-NEXT: sbbl %ebx, %edx 1103; X86-NEXT: sbbl %ebx, %ecx 1104; X86-NEXT: movl %edi, (%eax) 1105; X86-NEXT: movl %esi, 4(%eax) 1106; X86-NEXT: movl %edx, 8(%eax) 1107; X86-NEXT: movl %ecx, 12(%eax) 1108; X86-NEXT: popl %esi 1109; X86-NEXT: popl %edi 1110; X86-NEXT: popl %ebx 1111; X86-NEXT: retl $4 1112; 1113; X64-LABEL: abd_subnsw_i128_undef: 1114; X64: # %bb.0: 1115; X64-NEXT: movq %rdi, %rax 1116; X64-NEXT: subq %rdx, %rax 1117; X64-NEXT: sbbq %rcx, %rsi 1118; X64-NEXT: movq %rsi, %rcx 1119; X64-NEXT: sarq $63, %rcx 1120; X64-NEXT: xorq %rcx, %rsi 1121; X64-NEXT: xorq %rcx, %rax 1122; X64-NEXT: subq %rcx, %rax 1123; X64-NEXT: sbbq %rcx, %rsi 1124; X64-NEXT: movq %rsi, %rdx 1125; X64-NEXT: retq 1126 %sub = sub nsw i128 %a, %b 1127 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true) 1128 ret i128 %abs 1129} 1130 1131; 1132; negative tests 1133; 1134 1135define i32 @abd_sub_i32(i32 %a, i32 %b) nounwind { 1136; X86-LABEL: abd_sub_i32: 1137; X86: # %bb.0: 1138; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1139; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1140; X86-NEXT: movl %ecx, %eax 1141; X86-NEXT: negl %eax 1142; X86-NEXT: cmovsl %ecx, %eax 1143; X86-NEXT: retl 1144; 1145; X64-LABEL: abd_sub_i32: 1146; X64: # %bb.0: 1147; X64-NEXT: subl %esi, %edi 1148; X64-NEXT: movl %edi, %eax 1149; X64-NEXT: negl %eax 1150; X64-NEXT: cmovsl %edi, %eax 1151; X64-NEXT: retq 1152 %sub = sub i32 %a, %b 1153 %abs = call i32 @llvm.abs.i32(i32 %sub, i1 false) 1154 ret i32 %abs 1155} 1156 1157; 1158; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abds(a,b) 1159; 1160 1161define i8 @abd_select_i8(i8 %a, i8 %b) nounwind { 1162; X86-LABEL: abd_select_i8: 1163; X86: # %bb.0: 1164; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 1165; X86-NEXT: movsbl {{[0-9]+}}(%esp), %ecx 1166; X86-NEXT: movl %ecx, %edx 1167; X86-NEXT: subl %eax, %edx 1168; X86-NEXT: subl %ecx, %eax 1169; X86-NEXT: cmovll %edx, %eax 1170; X86-NEXT: # kill: def $al killed $al killed $eax 1171; X86-NEXT: retl 1172; 1173; X64-LABEL: abd_select_i8: 1174; X64: # %bb.0: 1175; X64-NEXT: movsbl %sil, %eax 1176; X64-NEXT: movsbl %dil, %ecx 1177; X64-NEXT: movl %ecx, %edx 1178; X64-NEXT: subl %eax, %edx 1179; X64-NEXT: subl %ecx, %eax 1180; X64-NEXT: cmovll %edx, %eax 1181; X64-NEXT: # kill: def $al killed $al killed $eax 1182; X64-NEXT: retq 1183 %cmp = icmp slt i8 %a, %b 1184 %ab = select i1 %cmp, i8 %a, i8 %b 1185 %ba = select i1 %cmp, i8 %b, i8 %a 1186 %sub = sub i8 %ba, %ab 1187 ret i8 %sub 1188} 1189 1190define i16 @abd_select_i16(i16 %a, i16 %b) nounwind { 1191; X86-LABEL: abd_select_i16: 1192; X86: # %bb.0: 1193; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax 1194; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx 1195; X86-NEXT: movl %ecx, %edx 1196; X86-NEXT: subl %eax, %edx 1197; X86-NEXT: subl %ecx, %eax 1198; X86-NEXT: cmovll %edx, %eax 1199; X86-NEXT: # kill: def $ax killed $ax killed $eax 1200; X86-NEXT: retl 1201; 1202; X64-LABEL: abd_select_i16: 1203; X64: # %bb.0: 1204; X64-NEXT: movswl %si, %eax 1205; X64-NEXT: movswl %di, %ecx 1206; X64-NEXT: movl %ecx, %edx 1207; X64-NEXT: subl %eax, %edx 1208; X64-NEXT: subl %ecx, %eax 1209; X64-NEXT: cmovll %edx, %eax 1210; X64-NEXT: # kill: def $ax killed $ax killed $eax 1211; X64-NEXT: retq 1212 %cmp = icmp sle i16 %a, %b 1213 %ab = select i1 %cmp, i16 %a, i16 %b 1214 %ba = select i1 %cmp, i16 %b, i16 %a 1215 %sub = sub i16 %ba, %ab 1216 ret i16 %sub 1217} 1218 1219define i32 @abd_select_i32(i32 %a, i32 %b) nounwind { 1220; X86-LABEL: abd_select_i32: 1221; X86: # %bb.0: 1222; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1223; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1224; X86-NEXT: movl %ecx, %edx 1225; X86-NEXT: subl %eax, %edx 1226; X86-NEXT: subl %ecx, %eax 1227; X86-NEXT: cmovll %edx, %eax 1228; X86-NEXT: retl 1229; 1230; X64-LABEL: abd_select_i32: 1231; X64: # %bb.0: 1232; X64-NEXT: movl %edi, %eax 1233; X64-NEXT: subl %esi, %eax 1234; X64-NEXT: subl %edi, %esi 1235; X64-NEXT: cmovgel %esi, %eax 1236; X64-NEXT: retq 1237 %cmp = icmp sgt i32 %a, %b 1238 %ab = select i1 %cmp, i32 %a, i32 %b 1239 %ba = select i1 %cmp, i32 %b, i32 %a 1240 %sub = sub i32 %ab, %ba 1241 ret i32 %sub 1242} 1243 1244define i64 @abd_select_i64(i64 %a, i64 %b) nounwind { 1245; X86-LABEL: abd_select_i64: 1246; X86: # %bb.0: 1247; X86-NEXT: pushl %ebx 1248; X86-NEXT: pushl %edi 1249; X86-NEXT: pushl %esi 1250; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1251; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1252; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1253; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1254; X86-NEXT: movl %ecx, %edi 1255; X86-NEXT: subl %eax, %edi 1256; X86-NEXT: movl %esi, %ebx 1257; X86-NEXT: sbbl %edx, %ebx 1258; X86-NEXT: subl %ecx, %eax 1259; X86-NEXT: sbbl %esi, %edx 1260; X86-NEXT: cmovll %edi, %eax 1261; X86-NEXT: cmovll %ebx, %edx 1262; X86-NEXT: popl %esi 1263; X86-NEXT: popl %edi 1264; X86-NEXT: popl %ebx 1265; X86-NEXT: retl 1266; 1267; X64-LABEL: abd_select_i64: 1268; X64: # %bb.0: 1269; X64-NEXT: movq %rdi, %rax 1270; X64-NEXT: subq %rsi, %rax 1271; X64-NEXT: subq %rdi, %rsi 1272; X64-NEXT: cmovgeq %rsi, %rax 1273; X64-NEXT: retq 1274 %cmp = icmp sge i64 %a, %b 1275 %ab = select i1 %cmp, i64 %a, i64 %b 1276 %ba = select i1 %cmp, i64 %b, i64 %a 1277 %sub = sub i64 %ab, %ba 1278 ret i64 %sub 1279} 1280 1281define i128 @abd_select_i128(i128 %a, i128 %b) nounwind { 1282; X86-LABEL: abd_select_i128: 1283; X86: # %bb.0: 1284; X86-NEXT: pushl %ebp 1285; X86-NEXT: pushl %ebx 1286; X86-NEXT: pushl %edi 1287; X86-NEXT: pushl %esi 1288; X86-NEXT: pushl %eax 1289; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1290; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1291; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1292; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1293; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 1294; X86-NEXT: subl %edx, %eax 1295; X86-NEXT: movl %eax, (%esp) # 4-byte Spill 1296; X86-NEXT: sbbl %esi, %ebx 1297; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 1298; X86-NEXT: sbbl %ecx, %ebp 1299; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 1300; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1301; X86-NEXT: sbbl %edi, %eax 1302; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 1303; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 1304; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 1305; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edi 1306; X86-NEXT: cmovll (%esp), %edx # 4-byte Folded Reload 1307; X86-NEXT: cmovll %ebx, %esi 1308; X86-NEXT: cmovll %ebp, %ecx 1309; X86-NEXT: cmovll %eax, %edi 1310; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1311; X86-NEXT: movl %edi, 12(%eax) 1312; X86-NEXT: movl %ecx, 8(%eax) 1313; X86-NEXT: movl %esi, 4(%eax) 1314; X86-NEXT: movl %edx, (%eax) 1315; X86-NEXT: addl $4, %esp 1316; X86-NEXT: popl %esi 1317; X86-NEXT: popl %edi 1318; X86-NEXT: popl %ebx 1319; X86-NEXT: popl %ebp 1320; X86-NEXT: retl $4 1321; 1322; X64-LABEL: abd_select_i128: 1323; X64: # %bb.0: 1324; X64-NEXT: movq %rdi, %rax 1325; X64-NEXT: subq %rdx, %rax 1326; X64-NEXT: movq %rsi, %r8 1327; X64-NEXT: sbbq %rcx, %r8 1328; X64-NEXT: subq %rdi, %rdx 1329; X64-NEXT: sbbq %rsi, %rcx 1330; X64-NEXT: cmovgeq %rdx, %rax 1331; X64-NEXT: cmovgeq %rcx, %r8 1332; X64-NEXT: movq %r8, %rdx 1333; X64-NEXT: retq 1334 %cmp = icmp slt i128 %a, %b 1335 %ab = select i1 %cmp, i128 %a, i128 %b 1336 %ba = select i1 %cmp, i128 %b, i128 %a 1337 %sub = sub i128 %ba, %ab 1338 ret i128 %sub 1339} 1340 1341declare i8 @llvm.abs.i8(i8, i1) 1342declare i16 @llvm.abs.i16(i16, i1) 1343declare i32 @llvm.abs.i32(i32, i1) 1344declare i64 @llvm.abs.i64(i64, i1) 1345declare i128 @llvm.abs.i128(i128, i1) 1346 1347declare i8 @llvm.smax.i8(i8, i8) 1348declare i16 @llvm.smax.i16(i16, i16) 1349declare i32 @llvm.smax.i32(i32, i32) 1350declare i64 @llvm.smax.i64(i64, i64) 1351 1352declare i8 @llvm.smin.i8(i8, i8) 1353declare i16 @llvm.smin.i16(i16, i16) 1354declare i32 @llvm.smin.i32(i32, i32) 1355declare i64 @llvm.smin.i64(i64, i64) 1356