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(nabs(sub(zext(a),zext(b)))) -> nabds(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), %eax 13; X86-NEXT: movzbl {{[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: cmovbl %edx, %eax 18; X86-NEXT: negb %al 19; X86-NEXT: # kill: def $al killed $al killed $eax 20; X86-NEXT: retl 21; 22; X64-LABEL: abd_ext_i8: 23; X64: # %bb.0: 24; X64-NEXT: movzbl %sil, %eax 25; X64-NEXT: movzbl %dil, %ecx 26; X64-NEXT: movl %ecx, %edx 27; X64-NEXT: subl %eax, %edx 28; X64-NEXT: subl %ecx, %eax 29; X64-NEXT: cmovbl %edx, %eax 30; X64-NEXT: negb %al 31; X64-NEXT: # kill: def $al killed $al killed $eax 32; X64-NEXT: retq 33 %aext = zext i8 %a to i64 34 %bext = zext i8 %b to i64 35 %sub = sub i64 %aext, %bext 36 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 37 %nabs = sub i64 0, %abs 38 %trunc = trunc i64 %nabs to i8 39 ret i8 %trunc 40} 41 42define i8 @abd_ext_i8_i16(i8 %a, i16 %b) nounwind { 43; X86-LABEL: abd_ext_i8_i16: 44; X86: # %bb.0: 45; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 46; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 47; X86-NEXT: movl %ecx, %edx 48; X86-NEXT: subl %eax, %edx 49; X86-NEXT: subl %ecx, %eax 50; X86-NEXT: cmovbl %edx, %eax 51; X86-NEXT: negb %al 52; X86-NEXT: # kill: def $al killed $al killed $eax 53; X86-NEXT: retl 54; 55; X64-LABEL: abd_ext_i8_i16: 56; X64: # %bb.0: 57; X64-NEXT: movzbl %dil, %ecx 58; X64-NEXT: subl %esi, %edi 59; X64-NEXT: movzwl %si, %eax 60; X64-NEXT: subl %ecx, %eax 61; X64-NEXT: cmovbl %edi, %eax 62; X64-NEXT: negb %al 63; X64-NEXT: # kill: def $al killed $al killed $eax 64; X64-NEXT: retq 65 %aext = zext i8 %a to i64 66 %bext = zext i16 %b to i64 67 %sub = sub i64 %aext, %bext 68 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 69 %nabs = sub i64 0, %abs 70 %trunc = trunc i64 %nabs to i8 71 ret i8 %trunc 72} 73 74define i8 @abd_ext_i8_undef(i8 %a, i8 %b) nounwind { 75; X86-LABEL: abd_ext_i8_undef: 76; X86: # %bb.0: 77; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 78; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 79; X86-NEXT: movl %ecx, %edx 80; X86-NEXT: subl %eax, %edx 81; X86-NEXT: subl %ecx, %eax 82; X86-NEXT: cmovbl %edx, %eax 83; X86-NEXT: negb %al 84; X86-NEXT: # kill: def $al killed $al killed $eax 85; X86-NEXT: retl 86; 87; X64-LABEL: abd_ext_i8_undef: 88; X64: # %bb.0: 89; X64-NEXT: movzbl %sil, %eax 90; X64-NEXT: movzbl %dil, %ecx 91; X64-NEXT: movl %ecx, %edx 92; X64-NEXT: subl %eax, %edx 93; X64-NEXT: subl %ecx, %eax 94; X64-NEXT: cmovbl %edx, %eax 95; X64-NEXT: negb %al 96; X64-NEXT: # kill: def $al killed $al killed $eax 97; X64-NEXT: retq 98 %aext = zext i8 %a to i64 99 %bext = zext i8 %b to i64 100 %sub = sub i64 %aext, %bext 101 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 102 %nabs = sub i64 0, %abs 103 %trunc = trunc i64 %nabs to i8 104 ret i8 %trunc 105} 106 107define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind { 108; X86-LABEL: abd_ext_i16: 109; X86: # %bb.0: 110; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 111; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 112; X86-NEXT: movl %ecx, %edx 113; X86-NEXT: subl %eax, %edx 114; X86-NEXT: subl %ecx, %eax 115; X86-NEXT: cmovael %edx, %eax 116; X86-NEXT: # kill: def $ax killed $ax killed $eax 117; X86-NEXT: retl 118; 119; X64-LABEL: abd_ext_i16: 120; X64: # %bb.0: 121; X64-NEXT: movzwl %di, %ecx 122; X64-NEXT: subl %esi, %edi 123; X64-NEXT: movzwl %si, %eax 124; X64-NEXT: subl %ecx, %eax 125; X64-NEXT: cmovbl %edi, %eax 126; X64-NEXT: negl %eax 127; X64-NEXT: # kill: def $ax killed $ax killed $eax 128; X64-NEXT: retq 129 %aext = zext i16 %a to i64 130 %bext = zext i16 %b to i64 131 %sub = sub i64 %aext, %bext 132 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 133 %nabs = sub i64 0, %abs 134 %trunc = trunc i64 %nabs to i16 135 ret i16 %trunc 136} 137 138define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind { 139; X86-LABEL: abd_ext_i16_i32: 140; X86: # %bb.0: 141; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 142; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 143; X86-NEXT: movl %ecx, %edx 144; X86-NEXT: subl %eax, %edx 145; X86-NEXT: subl %ecx, %eax 146; X86-NEXT: cmovael %edx, %eax 147; X86-NEXT: # kill: def $ax killed $ax killed $eax 148; X86-NEXT: retl 149; 150; X64-LABEL: abd_ext_i16_i32: 151; X64: # %bb.0: 152; X64-NEXT: movzwl %di, %ecx 153; X64-NEXT: movl %edi, %eax 154; X64-NEXT: subl %esi, %eax 155; X64-NEXT: subl %ecx, %esi 156; X64-NEXT: cmovael %esi, %eax 157; X64-NEXT: negl %eax 158; X64-NEXT: # kill: def $ax killed $ax killed $eax 159; X64-NEXT: retq 160 %aext = zext i16 %a to i64 161 %bext = zext i32 %b to i64 162 %sub = sub i64 %aext, %bext 163 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 164 %nabs = sub i64 0, %abs 165 %trunc = trunc i64 %nabs to i16 166 ret i16 %trunc 167} 168 169define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind { 170; X86-LABEL: abd_ext_i16_undef: 171; X86: # %bb.0: 172; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 173; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 174; X86-NEXT: movl %ecx, %edx 175; X86-NEXT: subl %eax, %edx 176; X86-NEXT: subl %ecx, %eax 177; X86-NEXT: cmovael %edx, %eax 178; X86-NEXT: # kill: def $ax killed $ax killed $eax 179; X86-NEXT: retl 180; 181; X64-LABEL: abd_ext_i16_undef: 182; X64: # %bb.0: 183; X64-NEXT: movzwl %di, %ecx 184; X64-NEXT: subl %esi, %edi 185; X64-NEXT: movzwl %si, %eax 186; X64-NEXT: subl %ecx, %eax 187; X64-NEXT: cmovbl %edi, %eax 188; X64-NEXT: negl %eax 189; X64-NEXT: # kill: def $ax killed $ax killed $eax 190; X64-NEXT: retq 191 %aext = zext i16 %a to i64 192 %bext = zext i16 %b to i64 193 %sub = sub i64 %aext, %bext 194 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 195 %nabs = sub i64 0, %abs 196 %trunc = trunc i64 %nabs to i16 197 ret i16 %trunc 198} 199 200define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { 201; X86-LABEL: abd_ext_i32: 202; X86: # %bb.0: 203; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 204; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 205; X86-NEXT: movl %ecx, %edx 206; X86-NEXT: subl %eax, %edx 207; X86-NEXT: subl %ecx, %eax 208; X86-NEXT: cmovael %edx, %eax 209; X86-NEXT: retl 210; 211; X64-LABEL: abd_ext_i32: 212; X64: # %bb.0: 213; X64-NEXT: movl %edi, %eax 214; X64-NEXT: subl %esi, %eax 215; X64-NEXT: subl %edi, %esi 216; X64-NEXT: cmovbl %esi, %eax 217; X64-NEXT: retq 218 %aext = zext i32 %a to i64 219 %bext = zext i32 %b to i64 220 %sub = sub i64 %aext, %bext 221 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 222 %nabs = sub i64 0, %abs 223 %trunc = trunc i64 %nabs to i32 224 ret i32 %trunc 225} 226 227define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { 228; X86-LABEL: abd_ext_i32_i16: 229; X86: # %bb.0: 230; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 231; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 232; X86-NEXT: movl %ecx, %edx 233; X86-NEXT: subl %eax, %edx 234; X86-NEXT: subl %ecx, %eax 235; X86-NEXT: cmovael %edx, %eax 236; X86-NEXT: retl 237; 238; X64-LABEL: abd_ext_i32_i16: 239; X64: # %bb.0: 240; X64-NEXT: movzwl %si, %eax 241; X64-NEXT: movl %edi, %ecx 242; X64-NEXT: subl %eax, %ecx 243; X64-NEXT: subl %edi, %eax 244; X64-NEXT: cmovael %ecx, %eax 245; X64-NEXT: retq 246 %aext = zext i32 %a to i64 247 %bext = zext i16 %b to i64 248 %sub = sub i64 %aext, %bext 249 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 false) 250 %nabs = sub i64 0, %abs 251 %trunc = trunc i64 %nabs to i32 252 ret i32 %trunc 253} 254 255define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind { 256; X86-LABEL: abd_ext_i32_undef: 257; X86: # %bb.0: 258; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 259; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 260; X86-NEXT: movl %ecx, %edx 261; X86-NEXT: subl %eax, %edx 262; X86-NEXT: subl %ecx, %eax 263; X86-NEXT: cmovael %edx, %eax 264; X86-NEXT: retl 265; 266; X64-LABEL: abd_ext_i32_undef: 267; X64: # %bb.0: 268; X64-NEXT: movl %edi, %eax 269; X64-NEXT: subl %esi, %eax 270; X64-NEXT: subl %edi, %esi 271; X64-NEXT: cmovbl %esi, %eax 272; X64-NEXT: retq 273 %aext = zext i32 %a to i64 274 %bext = zext i32 %b to i64 275 %sub = sub i64 %aext, %bext 276 %abs = call i64 @llvm.abs.i64(i64 %sub, i1 true) 277 %nabs = sub i64 0, %abs 278 %trunc = trunc i64 %nabs to i32 279 ret i32 %trunc 280} 281 282define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind { 283; X86-LABEL: abd_ext_i64: 284; X86: # %bb.0: 285; X86-NEXT: pushl %esi 286; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 287; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 288; X86-NEXT: xorl %edx, %edx 289; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 290; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 291; X86-NEXT: movl $0, %esi 292; X86-NEXT: sbbl %esi, %esi 293; X86-NEXT: xorl %esi, %ecx 294; X86-NEXT: xorl %esi, %eax 295; X86-NEXT: subl %esi, %eax 296; X86-NEXT: sbbl %esi, %ecx 297; X86-NEXT: negl %eax 298; X86-NEXT: sbbl %ecx, %edx 299; X86-NEXT: popl %esi 300; X86-NEXT: retl 301; 302; X64-LABEL: abd_ext_i64: 303; X64: # %bb.0: 304; X64-NEXT: movq %rdi, %rax 305; X64-NEXT: subq %rsi, %rax 306; X64-NEXT: subq %rdi, %rsi 307; X64-NEXT: cmovbq %rsi, %rax 308; X64-NEXT: retq 309 %aext = zext i64 %a to i128 310 %bext = zext i64 %b to i128 311 %sub = sub i128 %aext, %bext 312 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false) 313 %nabs = sub i128 0, %abs 314 %trunc = trunc i128 %nabs to i64 315 ret i64 %trunc 316} 317 318define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind { 319; X86-LABEL: abd_ext_i64_undef: 320; X86: # %bb.0: 321; X86-NEXT: pushl %esi 322; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 323; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 324; X86-NEXT: xorl %edx, %edx 325; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 326; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 327; X86-NEXT: movl $0, %esi 328; X86-NEXT: sbbl %esi, %esi 329; X86-NEXT: xorl %esi, %ecx 330; X86-NEXT: xorl %esi, %eax 331; X86-NEXT: subl %esi, %eax 332; X86-NEXT: sbbl %esi, %ecx 333; X86-NEXT: negl %eax 334; X86-NEXT: sbbl %ecx, %edx 335; X86-NEXT: popl %esi 336; X86-NEXT: retl 337; 338; X64-LABEL: abd_ext_i64_undef: 339; X64: # %bb.0: 340; X64-NEXT: movq %rdi, %rax 341; X64-NEXT: subq %rsi, %rax 342; X64-NEXT: subq %rdi, %rsi 343; X64-NEXT: cmovbq %rsi, %rax 344; X64-NEXT: retq 345 %aext = zext i64 %a to i128 346 %bext = zext i64 %b to i128 347 %sub = sub i128 %aext, %bext 348 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true) 349 %nabs = sub i128 0, %abs 350 %trunc = trunc i128 %nabs to i64 351 ret i64 %trunc 352} 353 354define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind { 355; X86-LABEL: abd_ext_i128: 356; X86: # %bb.0: 357; X86-NEXT: pushl %ebp 358; X86-NEXT: pushl %ebx 359; X86-NEXT: pushl %edi 360; X86-NEXT: pushl %esi 361; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 362; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 363; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 364; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 365; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 366; X86-NEXT: xorl %edi, %edi 367; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 368; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ebx 369; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 370; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 371; X86-NEXT: movl $0, %ebp 372; X86-NEXT: sbbl %ebp, %ebp 373; X86-NEXT: xorl %ebp, %ecx 374; X86-NEXT: xorl %ebp, %esi 375; X86-NEXT: xorl %ebp, %ebx 376; X86-NEXT: xorl %ebp, %edx 377; X86-NEXT: subl %ebp, %edx 378; X86-NEXT: sbbl %ebp, %ebx 379; X86-NEXT: sbbl %ebp, %esi 380; X86-NEXT: sbbl %ebp, %ecx 381; X86-NEXT: negl %edx 382; X86-NEXT: movl $0, %ebp 383; X86-NEXT: sbbl %ebx, %ebp 384; X86-NEXT: movl $0, %ebx 385; X86-NEXT: sbbl %esi, %ebx 386; X86-NEXT: sbbl %ecx, %edi 387; X86-NEXT: movl %edx, (%eax) 388; X86-NEXT: movl %ebp, 4(%eax) 389; X86-NEXT: movl %ebx, 8(%eax) 390; X86-NEXT: movl %edi, 12(%eax) 391; X86-NEXT: popl %esi 392; X86-NEXT: popl %edi 393; X86-NEXT: popl %ebx 394; X86-NEXT: popl %ebp 395; X86-NEXT: retl $4 396; 397; X64-LABEL: abd_ext_i128: 398; X64: # %bb.0: 399; X64-NEXT: movq %rdi, %rax 400; X64-NEXT: xorl %edi, %edi 401; X64-NEXT: subq %rdx, %rax 402; X64-NEXT: sbbq %rcx, %rsi 403; X64-NEXT: movl $0, %ecx 404; X64-NEXT: sbbq %rcx, %rcx 405; X64-NEXT: xorq %rcx, %rsi 406; X64-NEXT: xorq %rcx, %rax 407; X64-NEXT: subq %rcx, %rax 408; X64-NEXT: sbbq %rcx, %rsi 409; X64-NEXT: negq %rax 410; X64-NEXT: sbbq %rsi, %rdi 411; X64-NEXT: movq %rdi, %rdx 412; X64-NEXT: retq 413 %aext = zext i128 %a to i256 414 %bext = zext i128 %b to i256 415 %sub = sub i256 %aext, %bext 416 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false) 417 %nabs = sub i256 0, %abs 418 %trunc = trunc i256 %nabs to i128 419 ret i128 %trunc 420} 421 422define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind { 423; X86-LABEL: abd_ext_i128_undef: 424; X86: # %bb.0: 425; X86-NEXT: pushl %ebp 426; X86-NEXT: pushl %ebx 427; X86-NEXT: pushl %edi 428; X86-NEXT: pushl %esi 429; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 430; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 431; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 432; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 433; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 434; X86-NEXT: xorl %edi, %edi 435; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 436; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ebx 437; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 438; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 439; X86-NEXT: movl $0, %ebp 440; X86-NEXT: sbbl %ebp, %ebp 441; X86-NEXT: xorl %ebp, %ecx 442; X86-NEXT: xorl %ebp, %esi 443; X86-NEXT: xorl %ebp, %ebx 444; X86-NEXT: xorl %ebp, %edx 445; X86-NEXT: subl %ebp, %edx 446; X86-NEXT: sbbl %ebp, %ebx 447; X86-NEXT: sbbl %ebp, %esi 448; X86-NEXT: sbbl %ebp, %ecx 449; X86-NEXT: negl %edx 450; X86-NEXT: movl $0, %ebp 451; X86-NEXT: sbbl %ebx, %ebp 452; X86-NEXT: movl $0, %ebx 453; X86-NEXT: sbbl %esi, %ebx 454; X86-NEXT: sbbl %ecx, %edi 455; X86-NEXT: movl %edx, (%eax) 456; X86-NEXT: movl %ebp, 4(%eax) 457; X86-NEXT: movl %ebx, 8(%eax) 458; X86-NEXT: movl %edi, 12(%eax) 459; X86-NEXT: popl %esi 460; X86-NEXT: popl %edi 461; X86-NEXT: popl %ebx 462; X86-NEXT: popl %ebp 463; X86-NEXT: retl $4 464; 465; X64-LABEL: abd_ext_i128_undef: 466; X64: # %bb.0: 467; X64-NEXT: movq %rdi, %rax 468; X64-NEXT: xorl %edi, %edi 469; X64-NEXT: subq %rdx, %rax 470; X64-NEXT: sbbq %rcx, %rsi 471; X64-NEXT: movl $0, %ecx 472; X64-NEXT: sbbq %rcx, %rcx 473; X64-NEXT: xorq %rcx, %rsi 474; X64-NEXT: xorq %rcx, %rax 475; X64-NEXT: subq %rcx, %rax 476; X64-NEXT: sbbq %rcx, %rsi 477; X64-NEXT: negq %rax 478; X64-NEXT: sbbq %rsi, %rdi 479; X64-NEXT: movq %rdi, %rdx 480; X64-NEXT: retq 481 %aext = zext i128 %a to i256 482 %bext = zext i128 %b to i256 483 %sub = sub i256 %aext, %bext 484 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true) 485 %nabs = sub i256 0, %abs 486 %trunc = trunc i256 %nabs to i128 487 ret i128 %trunc 488} 489 490; 491; sub(umin(a,b),umax(a,b)) -> nabds(a,b) 492; 493 494define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind { 495; X86-LABEL: abd_minmax_i8: 496; X86: # %bb.0: 497; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 498; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 499; X86-NEXT: movl %ecx, %edx 500; X86-NEXT: subl %eax, %edx 501; X86-NEXT: subl %ecx, %eax 502; X86-NEXT: cmovbl %edx, %eax 503; X86-NEXT: negb %al 504; X86-NEXT: # kill: def $al killed $al killed $eax 505; X86-NEXT: retl 506; 507; X64-LABEL: abd_minmax_i8: 508; X64: # %bb.0: 509; X64-NEXT: movzbl %sil, %eax 510; X64-NEXT: movzbl %dil, %ecx 511; X64-NEXT: movl %ecx, %edx 512; X64-NEXT: subl %eax, %edx 513; X64-NEXT: subl %ecx, %eax 514; X64-NEXT: cmovbl %edx, %eax 515; X64-NEXT: negb %al 516; X64-NEXT: # kill: def $al killed $al killed $eax 517; X64-NEXT: retq 518 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b) 519 %max = call i8 @llvm.umax.i8(i8 %a, i8 %b) 520 %sub = sub i8 %min, %max 521 ret i8 %sub 522} 523 524define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind { 525; X86-LABEL: abd_minmax_i16: 526; X86: # %bb.0: 527; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 528; X86-NEXT: movzwl {{[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: cmovael %edx, %eax 533; X86-NEXT: # kill: def $ax killed $ax killed $eax 534; X86-NEXT: retl 535; 536; X64-LABEL: abd_minmax_i16: 537; X64: # %bb.0: 538; X64-NEXT: movzwl %di, %ecx 539; X64-NEXT: subl %esi, %edi 540; X64-NEXT: movzwl %si, %eax 541; X64-NEXT: subl %ecx, %eax 542; X64-NEXT: cmovbl %edi, %eax 543; X64-NEXT: negl %eax 544; X64-NEXT: # kill: def $ax killed $ax killed $eax 545; X64-NEXT: retq 546 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b) 547 %max = call i16 @llvm.umax.i16(i16 %a, i16 %b) 548 %sub = sub i16 %min, %max 549 ret i16 %sub 550} 551 552define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind { 553; X86-LABEL: abd_minmax_i32: 554; X86: # %bb.0: 555; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 556; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 557; X86-NEXT: movl %ecx, %edx 558; X86-NEXT: subl %eax, %edx 559; X86-NEXT: subl %ecx, %eax 560; X86-NEXT: cmovael %edx, %eax 561; X86-NEXT: retl 562; 563; X64-LABEL: abd_minmax_i32: 564; X64: # %bb.0: 565; X64-NEXT: movl %edi, %eax 566; X64-NEXT: subl %esi, %eax 567; X64-NEXT: subl %edi, %esi 568; X64-NEXT: cmovbl %esi, %eax 569; X64-NEXT: retq 570 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b) 571 %max = call i32 @llvm.umax.i32(i32 %a, i32 %b) 572 %sub = sub i32 %min, %max 573 ret i32 %sub 574} 575 576define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind { 577; X86-LABEL: abd_minmax_i64: 578; X86: # %bb.0: 579; X86-NEXT: pushl %ebp 580; X86-NEXT: pushl %ebx 581; X86-NEXT: pushl %edi 582; X86-NEXT: pushl %esi 583; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 584; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 585; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 586; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 587; X86-NEXT: cmpl %esi, %edi 588; X86-NEXT: movl %ebx, %eax 589; X86-NEXT: sbbl %ecx, %eax 590; X86-NEXT: movl %ecx, %edx 591; X86-NEXT: cmovbl %ebx, %edx 592; X86-NEXT: movl %esi, %eax 593; X86-NEXT: cmovbl %edi, %eax 594; X86-NEXT: cmpl %edi, %esi 595; X86-NEXT: movl %ecx, %ebp 596; X86-NEXT: sbbl %ebx, %ebp 597; X86-NEXT: cmovbl %ebx, %ecx 598; X86-NEXT: cmovbl %edi, %esi 599; X86-NEXT: subl %esi, %eax 600; X86-NEXT: sbbl %ecx, %edx 601; X86-NEXT: popl %esi 602; X86-NEXT: popl %edi 603; X86-NEXT: popl %ebx 604; X86-NEXT: popl %ebp 605; X86-NEXT: retl 606; 607; X64-LABEL: abd_minmax_i64: 608; X64: # %bb.0: 609; X64-NEXT: movq %rdi, %rax 610; X64-NEXT: subq %rsi, %rax 611; X64-NEXT: subq %rdi, %rsi 612; X64-NEXT: cmovbq %rsi, %rax 613; X64-NEXT: retq 614 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b) 615 %max = call i64 @llvm.umax.i64(i64 %a, i64 %b) 616 %sub = sub i64 %min, %max 617 ret i64 %sub 618} 619 620define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind { 621; X86-LABEL: abd_minmax_i128: 622; X86: # %bb.0: 623; X86-NEXT: pushl %ebp 624; X86-NEXT: pushl %ebx 625; X86-NEXT: pushl %edi 626; X86-NEXT: pushl %esi 627; X86-NEXT: pushl %eax 628; X86-NEXT: movl {{[0-9]+}}(%esp), %ebp 629; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 630; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 631; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 632; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 633; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 634; X86-NEXT: cmpl %eax, %esi 635; X86-NEXT: sbbl %ebx, %ecx 636; X86-NEXT: movl %edx, %ecx 637; X86-NEXT: sbbl %ebp, %ecx 638; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 639; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 640; X86-NEXT: movl %edx, %ecx 641; X86-NEXT: sbbl %edi, %ecx 642; X86-NEXT: movl %edi, %ecx 643; X86-NEXT: cmovbl %edx, %ecx 644; X86-NEXT: movl %ecx, (%esp) # 4-byte Spill 645; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %ebp 646; X86-NEXT: movl %ebx, %ecx 647; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %ecx 648; X86-NEXT: movl %eax, %edx 649; X86-NEXT: cmovbl %esi, %edx 650; X86-NEXT: cmpl %esi, %eax 651; X86-NEXT: movl %ebx, %esi 652; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 653; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 654; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 655; X86-NEXT: movl %edi, %esi 656; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 657; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %edi 658; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 659; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %esi 660; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %ebx 661; X86-NEXT: cmovbl {{[0-9]+}}(%esp), %eax 662; X86-NEXT: subl %eax, %edx 663; X86-NEXT: sbbl %ebx, %ecx 664; X86-NEXT: sbbl %esi, %ebp 665; X86-NEXT: movl (%esp), %esi # 4-byte Reload 666; X86-NEXT: sbbl %edi, %esi 667; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 668; X86-NEXT: movl %edx, (%eax) 669; X86-NEXT: movl %ecx, 4(%eax) 670; X86-NEXT: movl %ebp, 8(%eax) 671; X86-NEXT: movl %esi, 12(%eax) 672; X86-NEXT: addl $4, %esp 673; X86-NEXT: popl %esi 674; X86-NEXT: popl %edi 675; X86-NEXT: popl %ebx 676; X86-NEXT: popl %ebp 677; X86-NEXT: retl $4 678; 679; X64-LABEL: abd_minmax_i128: 680; X64: # %bb.0: 681; X64-NEXT: cmpq %rdx, %rdi 682; X64-NEXT: movq %rsi, %rax 683; X64-NEXT: sbbq %rcx, %rax 684; X64-NEXT: movq %rcx, %r8 685; X64-NEXT: cmovbq %rsi, %r8 686; X64-NEXT: movq %rdx, %rax 687; X64-NEXT: cmovbq %rdi, %rax 688; X64-NEXT: cmpq %rdi, %rdx 689; X64-NEXT: movq %rcx, %r9 690; X64-NEXT: sbbq %rsi, %r9 691; X64-NEXT: cmovbq %rsi, %rcx 692; X64-NEXT: cmovbq %rdi, %rdx 693; X64-NEXT: subq %rdx, %rax 694; X64-NEXT: sbbq %rcx, %r8 695; X64-NEXT: movq %r8, %rdx 696; X64-NEXT: retq 697 %min = call i128 @llvm.umin.i128(i128 %a, i128 %b) 698 %max = call i128 @llvm.umax.i128(i128 %a, i128 %b) 699 %sub = sub i128 %min, %max 700 ret i128 %sub 701} 702 703; 704; select(icmp(a,b),sub(a,b),sub(b,a)) -> nabds(a,b) 705; 706 707define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind { 708; X86-LABEL: abd_cmp_i8: 709; X86: # %bb.0: 710; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 711; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 712; X86-NEXT: movl %ecx, %edx 713; X86-NEXT: subl %eax, %edx 714; X86-NEXT: subl %ecx, %eax 715; X86-NEXT: cmovbl %edx, %eax 716; X86-NEXT: negb %al 717; X86-NEXT: # kill: def $al killed $al killed $eax 718; X86-NEXT: retl 719; 720; X64-LABEL: abd_cmp_i8: 721; X64: # %bb.0: 722; X64-NEXT: movzbl %sil, %eax 723; X64-NEXT: movzbl %dil, %ecx 724; X64-NEXT: movl %ecx, %edx 725; X64-NEXT: subl %eax, %edx 726; X64-NEXT: subl %ecx, %eax 727; X64-NEXT: cmovbl %edx, %eax 728; X64-NEXT: negb %al 729; X64-NEXT: # kill: def $al killed $al killed $eax 730; X64-NEXT: retq 731 %cmp = icmp ule i8 %a, %b 732 %ab = sub i8 %a, %b 733 %ba = sub i8 %b, %a 734 %sel = select i1 %cmp, i8 %ab, i8 %ba 735 ret i8 %sel 736} 737 738define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind { 739; X86-LABEL: abd_cmp_i16: 740; X86: # %bb.0: 741; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 742; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 743; X86-NEXT: movl %ecx, %edx 744; X86-NEXT: subl %eax, %edx 745; X86-NEXT: subl %ecx, %eax 746; X86-NEXT: cmovael %edx, %eax 747; X86-NEXT: # kill: def $ax killed $ax killed $eax 748; X86-NEXT: retl 749; 750; X64-LABEL: abd_cmp_i16: 751; X64: # %bb.0: 752; X64-NEXT: movzwl %di, %ecx 753; X64-NEXT: subl %esi, %edi 754; X64-NEXT: movzwl %si, %eax 755; X64-NEXT: subl %ecx, %eax 756; X64-NEXT: cmovbl %edi, %eax 757; X64-NEXT: negl %eax 758; X64-NEXT: # kill: def $ax killed $ax killed $eax 759; X64-NEXT: retq 760 %cmp = icmp ult i16 %a, %b 761 %ab = sub i16 %a, %b 762 %ba = sub i16 %b, %a 763 %sel = select i1 %cmp, i16 %ab, i16 %ba 764 ret i16 %sel 765} 766 767define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind { 768; X86-LABEL: abd_cmp_i32: 769; X86: # %bb.0: 770; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 771; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 772; X86-NEXT: movl %ecx, %edx 773; X86-NEXT: subl %eax, %edx 774; X86-NEXT: subl %ecx, %eax 775; X86-NEXT: cmovael %edx, %eax 776; X86-NEXT: retl 777; 778; X64-LABEL: abd_cmp_i32: 779; X64: # %bb.0: 780; X64-NEXT: movl %edi, %eax 781; X64-NEXT: subl %esi, %eax 782; X64-NEXT: subl %edi, %esi 783; X64-NEXT: cmovbl %esi, %eax 784; X64-NEXT: retq 785 %cmp = icmp uge i32 %a, %b 786 %ab = sub i32 %a, %b 787 %ba = sub i32 %b, %a 788 %sel = select i1 %cmp, i32 %ba, i32 %ab 789 ret i32 %sel 790} 791 792define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind { 793; X86-LABEL: abd_cmp_i64: 794; X86: # %bb.0: 795; X86-NEXT: pushl %esi 796; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 797; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 798; X86-NEXT: xorl %edx, %edx 799; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 800; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 801; X86-NEXT: movl $0, %esi 802; X86-NEXT: sbbl %esi, %esi 803; X86-NEXT: xorl %esi, %ecx 804; X86-NEXT: xorl %esi, %eax 805; X86-NEXT: subl %esi, %eax 806; X86-NEXT: sbbl %esi, %ecx 807; X86-NEXT: negl %eax 808; X86-NEXT: sbbl %ecx, %edx 809; X86-NEXT: popl %esi 810; X86-NEXT: retl 811; 812; X64-LABEL: abd_cmp_i64: 813; X64: # %bb.0: 814; X64-NEXT: movq %rdi, %rax 815; X64-NEXT: subq %rsi, %rax 816; X64-NEXT: subq %rdi, %rsi 817; X64-NEXT: cmovbq %rsi, %rax 818; X64-NEXT: retq 819 %cmp = icmp ult i64 %a, %b 820 %ab = sub i64 %a, %b 821 %ba = sub i64 %b, %a 822 %sel = select i1 %cmp, i64 %ab, i64 %ba 823 ret i64 %sel 824} 825 826define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind { 827; X86-LABEL: abd_cmp_i128: 828; X86: # %bb.0: 829; X86-NEXT: pushl %ebp 830; X86-NEXT: pushl %ebx 831; X86-NEXT: pushl %edi 832; X86-NEXT: pushl %esi 833; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 834; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 835; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 836; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx 837; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 838; X86-NEXT: xorl %edi, %edi 839; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 840; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ebx 841; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 842; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 843; X86-NEXT: movl $0, %ebp 844; X86-NEXT: sbbl %ebp, %ebp 845; X86-NEXT: xorl %ebp, %ecx 846; X86-NEXT: xorl %ebp, %esi 847; X86-NEXT: xorl %ebp, %ebx 848; X86-NEXT: xorl %ebp, %edx 849; X86-NEXT: subl %ebp, %edx 850; X86-NEXT: sbbl %ebp, %ebx 851; X86-NEXT: sbbl %ebp, %esi 852; X86-NEXT: sbbl %ebp, %ecx 853; X86-NEXT: negl %edx 854; X86-NEXT: movl $0, %ebp 855; X86-NEXT: sbbl %ebx, %ebp 856; X86-NEXT: movl $0, %ebx 857; X86-NEXT: sbbl %esi, %ebx 858; X86-NEXT: sbbl %ecx, %edi 859; X86-NEXT: movl %edx, (%eax) 860; X86-NEXT: movl %ebp, 4(%eax) 861; X86-NEXT: movl %ebx, 8(%eax) 862; X86-NEXT: movl %edi, 12(%eax) 863; X86-NEXT: popl %esi 864; X86-NEXT: popl %edi 865; X86-NEXT: popl %ebx 866; X86-NEXT: popl %ebp 867; X86-NEXT: retl $4 868; 869; X64-LABEL: abd_cmp_i128: 870; X64: # %bb.0: 871; X64-NEXT: movq %rdi, %rax 872; X64-NEXT: xorl %edi, %edi 873; X64-NEXT: subq %rdx, %rax 874; X64-NEXT: sbbq %rcx, %rsi 875; X64-NEXT: movl $0, %ecx 876; X64-NEXT: sbbq %rcx, %rcx 877; X64-NEXT: xorq %rcx, %rsi 878; X64-NEXT: xorq %rcx, %rax 879; X64-NEXT: subq %rcx, %rax 880; X64-NEXT: sbbq %rcx, %rsi 881; X64-NEXT: negq %rax 882; X64-NEXT: sbbq %rsi, %rdi 883; X64-NEXT: movq %rdi, %rdx 884; X64-NEXT: retq 885 %cmp = icmp ult i128 %a, %b 886 %ab = sub i128 %a, %b 887 %ba = sub i128 %b, %a 888 %sel = select i1 %cmp, i128 %ab, i128 %ba 889 ret i128 %sel 890} 891 892declare i8 @llvm.abs.i8(i8, i1) 893declare i16 @llvm.abs.i16(i16, i1) 894declare i32 @llvm.abs.i32(i32, i1) 895declare i64 @llvm.abs.i64(i64, i1) 896declare i128 @llvm.abs.i128(i128, i1) 897 898declare i8 @llvm.umax.i8(i8, i8) 899declare i16 @llvm.umax.i16(i16, i16) 900declare i32 @llvm.umax.i32(i32, i32) 901declare i64 @llvm.umax.i64(i64, i64) 902 903declare i8 @llvm.umin.i8(i8, i8) 904declare i16 @llvm.umin.i16(i16, i16) 905declare i32 @llvm.umin.i32(i32, i32) 906declare i64 @llvm.umin.i64(i64, i64) 907