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(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), %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: # 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: movzbl %sil, %eax 24; X64-NEXT: movzbl %dil, %ecx 25; X64-NEXT: movl %ecx, %edx 26; X64-NEXT: subl %eax, %edx 27; X64-NEXT: subl %ecx, %eax 28; X64-NEXT: cmovbl %edx, %eax 29; X64-NEXT: # kill: def $al killed $al killed $eax 30; X64-NEXT: retq 31 %aext = zext i8 %a to i64 32 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax 43; X86-NEXT: movzbl {{[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: cmovbl %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: movzbl %dil, %ecx 54; X64-NEXT: subl %esi, %edi 55; X64-NEXT: movzwl %si, %eax 56; X64-NEXT: subl %ecx, %eax 57; X64-NEXT: cmovbl %edi, %eax 58; X64-NEXT: # kill: def $al killed $al killed $eax 59; X64-NEXT: retq 60 %aext = zext i8 %a to i64 61 %bext = zext 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: movzbl {{[0-9]+}}(%esp), %eax 72; X86-NEXT: movzbl {{[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: cmovbl %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: movzbl %sil, %eax 83; X64-NEXT: movzbl %dil, %ecx 84; X64-NEXT: movl %ecx, %edx 85; X64-NEXT: subl %eax, %edx 86; X64-NEXT: subl %ecx, %eax 87; X64-NEXT: cmovbl %edx, %eax 88; X64-NEXT: # kill: def $al killed $al killed $eax 89; X64-NEXT: retq 90 %aext = zext i8 %a to i64 91 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax 102; X86-NEXT: movzwl {{[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: cmovbl %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: movzwl %si, %eax 113; X64-NEXT: movzwl %di, %ecx 114; X64-NEXT: movl %ecx, %edx 115; X64-NEXT: subl %eax, %edx 116; X64-NEXT: subl %ecx, %eax 117; X64-NEXT: cmovbl %edx, %eax 118; X64-NEXT: # kill: def $ax killed $ax killed $eax 119; X64-NEXT: retq 120 %aext = zext i16 %a to i64 121 %bext = zext 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: movzwl {{[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: cmovbl %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: movzwl %di, %ecx 143; X64-NEXT: movl %edi, %eax 144; X64-NEXT: subl %esi, %eax 145; X64-NEXT: subl %ecx, %esi 146; X64-NEXT: cmovael %esi, %eax 147; X64-NEXT: # kill: def $ax killed $ax killed $eax 148; X64-NEXT: retq 149 %aext = zext i16 %a to i64 150 %bext = zext 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: movzwl {{[0-9]+}}(%esp), %eax 161; X86-NEXT: movzwl {{[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: cmovbl %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: movzwl %si, %eax 172; X64-NEXT: movzwl %di, %ecx 173; X64-NEXT: movl %ecx, %edx 174; X64-NEXT: subl %eax, %edx 175; X64-NEXT: subl %ecx, %eax 176; X64-NEXT: cmovbl %edx, %eax 177; X64-NEXT: # kill: def $ax killed $ax killed $eax 178; X64-NEXT: retq 179 %aext = zext i16 %a to i64 180 %bext = zext 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: cmovbl %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: cmovael %esi, %eax 204; X64-NEXT: retq 205 %aext = zext i32 %a to i64 206 %bext = zext 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: movzwl {{[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: cmovbl %edx, %eax 222; X86-NEXT: retl 223; 224; X64-LABEL: abd_ext_i32_i16: 225; X64: # %bb.0: 226; X64-NEXT: movzwl %si, %eax 227; X64-NEXT: movl %edi, %ecx 228; X64-NEXT: subl %eax, %ecx 229; X64-NEXT: subl %edi, %eax 230; X64-NEXT: cmovbl %ecx, %eax 231; X64-NEXT: retq 232 %aext = zext i32 %a to i64 233 %bext = zext 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: cmovbl %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: cmovael %esi, %eax 257; X64-NEXT: retq 258 %aext = zext i32 %a to i64 259 %bext = zext 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: movl {{[0-9]+}}(%esp), %eax 270; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 271; X86-NEXT: xorl %ecx, %ecx 272; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 273; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 274; X86-NEXT: sbbl %ecx, %ecx 275; X86-NEXT: xorl %ecx, %edx 276; X86-NEXT: xorl %ecx, %eax 277; X86-NEXT: subl %ecx, %eax 278; X86-NEXT: sbbl %ecx, %edx 279; X86-NEXT: retl 280; 281; X64-LABEL: abd_ext_i64: 282; X64: # %bb.0: 283; X64-NEXT: movq %rdi, %rax 284; X64-NEXT: subq %rsi, %rax 285; X64-NEXT: subq %rdi, %rsi 286; X64-NEXT: cmovaeq %rsi, %rax 287; X64-NEXT: retq 288 %aext = zext i64 %a to i128 289 %bext = zext i64 %b to i128 290 %sub = sub i128 %aext, %bext 291 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 false) 292 %trunc = trunc i128 %abs to i64 293 ret i64 %trunc 294} 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), %eax 300; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 301; X86-NEXT: xorl %ecx, %ecx 302; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 303; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 304; X86-NEXT: sbbl %ecx, %ecx 305; X86-NEXT: xorl %ecx, %edx 306; X86-NEXT: xorl %ecx, %eax 307; X86-NEXT: subl %ecx, %eax 308; X86-NEXT: sbbl %ecx, %edx 309; X86-NEXT: retl 310; 311; X64-LABEL: abd_ext_i64_undef: 312; X64: # %bb.0: 313; X64-NEXT: movq %rdi, %rax 314; X64-NEXT: subq %rsi, %rax 315; X64-NEXT: subq %rdi, %rsi 316; X64-NEXT: cmovaeq %rsi, %rax 317; X64-NEXT: retq 318 %aext = zext i64 %a to i128 319 %bext = zext i64 %b to i128 320 %sub = sub i128 %aext, %bext 321 %abs = call i128 @llvm.abs.i128(i128 %sub, i1 true) 322 %trunc = trunc i128 %abs to i64 323 ret i64 %trunc 324} 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 %ebx 330; X86-NEXT: pushl %edi 331; X86-NEXT: pushl %esi 332; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 333; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 334; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 335; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 336; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 337; X86-NEXT: xorl %ebx, %ebx 338; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 339; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 340; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 341; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 342; X86-NEXT: sbbl %ebx, %ebx 343; X86-NEXT: xorl %ebx, %ecx 344; X86-NEXT: xorl %ebx, %edx 345; X86-NEXT: xorl %ebx, %esi 346; X86-NEXT: xorl %ebx, %edi 347; X86-NEXT: subl %ebx, %edi 348; X86-NEXT: sbbl %ebx, %esi 349; X86-NEXT: sbbl %ebx, %edx 350; X86-NEXT: sbbl %ebx, %ecx 351; X86-NEXT: movl %edi, (%eax) 352; X86-NEXT: movl %esi, 4(%eax) 353; X86-NEXT: movl %edx, 8(%eax) 354; X86-NEXT: movl %ecx, 12(%eax) 355; X86-NEXT: popl %esi 356; X86-NEXT: popl %edi 357; X86-NEXT: popl %ebx 358; X86-NEXT: retl $4 359; 360; X64-LABEL: abd_ext_i128: 361; X64: # %bb.0: 362; X64-NEXT: movq %rdi, %rax 363; X64-NEXT: xorl %edi, %edi 364; X64-NEXT: subq %rdx, %rax 365; X64-NEXT: sbbq %rcx, %rsi 366; X64-NEXT: sbbq %rdi, %rdi 367; X64-NEXT: xorq %rdi, %rsi 368; X64-NEXT: xorq %rdi, %rax 369; X64-NEXT: subq %rdi, %rax 370; X64-NEXT: sbbq %rdi, %rsi 371; X64-NEXT: movq %rsi, %rdx 372; X64-NEXT: retq 373 %aext = zext i128 %a to i256 374 %bext = zext i128 %b to i256 375 %sub = sub i256 %aext, %bext 376 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 false) 377 %trunc = trunc i256 %abs to i128 378 ret i128 %trunc 379} 380 381define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind { 382; X86-LABEL: abd_ext_i128_undef: 383; X86: # %bb.0: 384; X86-NEXT: pushl %ebx 385; X86-NEXT: pushl %edi 386; X86-NEXT: pushl %esi 387; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 388; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 389; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 390; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 391; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 392; X86-NEXT: xorl %ebx, %ebx 393; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 394; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 395; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 396; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 397; X86-NEXT: sbbl %ebx, %ebx 398; X86-NEXT: xorl %ebx, %ecx 399; X86-NEXT: xorl %ebx, %edx 400; X86-NEXT: xorl %ebx, %esi 401; X86-NEXT: xorl %ebx, %edi 402; X86-NEXT: subl %ebx, %edi 403; X86-NEXT: sbbl %ebx, %esi 404; X86-NEXT: sbbl %ebx, %edx 405; X86-NEXT: sbbl %ebx, %ecx 406; X86-NEXT: movl %edi, (%eax) 407; X86-NEXT: movl %esi, 4(%eax) 408; X86-NEXT: movl %edx, 8(%eax) 409; X86-NEXT: movl %ecx, 12(%eax) 410; X86-NEXT: popl %esi 411; X86-NEXT: popl %edi 412; X86-NEXT: popl %ebx 413; X86-NEXT: retl $4 414; 415; X64-LABEL: abd_ext_i128_undef: 416; X64: # %bb.0: 417; X64-NEXT: movq %rdi, %rax 418; X64-NEXT: xorl %edi, %edi 419; X64-NEXT: subq %rdx, %rax 420; X64-NEXT: sbbq %rcx, %rsi 421; X64-NEXT: sbbq %rdi, %rdi 422; X64-NEXT: xorq %rdi, %rsi 423; X64-NEXT: xorq %rdi, %rax 424; X64-NEXT: subq %rdi, %rax 425; X64-NEXT: sbbq %rdi, %rsi 426; X64-NEXT: movq %rsi, %rdx 427; X64-NEXT: retq 428 %aext = zext i128 %a to i256 429 %bext = zext i128 %b to i256 430 %sub = sub i256 %aext, %bext 431 %abs = call i256 @llvm.abs.i256(i256 %sub, i1 true) 432 %trunc = trunc i256 %abs to i128 433 ret i128 %trunc 434} 435 436; 437; sub(umax(a,b),umin(a,b)) -> abdu(a,b) 438; 439 440define i8 @abd_minmax_i8(i8 %a, i8 %b) nounwind { 441; X86-LABEL: abd_minmax_i8: 442; X86: # %bb.0: 443; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 444; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 445; X86-NEXT: movl %ecx, %edx 446; X86-NEXT: subl %eax, %edx 447; X86-NEXT: subl %ecx, %eax 448; X86-NEXT: cmovbl %edx, %eax 449; X86-NEXT: # kill: def $al killed $al killed $eax 450; X86-NEXT: retl 451; 452; X64-LABEL: abd_minmax_i8: 453; X64: # %bb.0: 454; X64-NEXT: movzbl %sil, %eax 455; X64-NEXT: movzbl %dil, %ecx 456; X64-NEXT: movl %ecx, %edx 457; X64-NEXT: subl %eax, %edx 458; X64-NEXT: subl %ecx, %eax 459; X64-NEXT: cmovbl %edx, %eax 460; X64-NEXT: # kill: def $al killed $al killed $eax 461; X64-NEXT: retq 462 %min = call i8 @llvm.umin.i8(i8 %a, i8 %b) 463 %max = call i8 @llvm.umax.i8(i8 %a, i8 %b) 464 %sub = sub i8 %max, %min 465 ret i8 %sub 466} 467 468define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind { 469; X86-LABEL: abd_minmax_i16: 470; X86: # %bb.0: 471; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 472; X86-NEXT: movzwl {{[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: cmovbl %edx, %eax 477; X86-NEXT: # kill: def $ax killed $ax killed $eax 478; X86-NEXT: retl 479; 480; X64-LABEL: abd_minmax_i16: 481; X64: # %bb.0: 482; X64-NEXT: movzwl %si, %eax 483; X64-NEXT: movzwl %di, %ecx 484; X64-NEXT: movl %ecx, %edx 485; X64-NEXT: subl %eax, %edx 486; X64-NEXT: subl %ecx, %eax 487; X64-NEXT: cmovbl %edx, %eax 488; X64-NEXT: # kill: def $ax killed $ax killed $eax 489; X64-NEXT: retq 490 %min = call i16 @llvm.umin.i16(i16 %a, i16 %b) 491 %max = call i16 @llvm.umax.i16(i16 %a, i16 %b) 492 %sub = sub i16 %max, %min 493 ret i16 %sub 494} 495 496define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind { 497; X86-LABEL: abd_minmax_i32: 498; X86: # %bb.0: 499; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 500; X86-NEXT: movl {{[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: cmovbl %edx, %eax 505; X86-NEXT: retl 506; 507; X64-LABEL: abd_minmax_i32: 508; X64: # %bb.0: 509; X64-NEXT: movl %edi, %eax 510; X64-NEXT: subl %esi, %eax 511; X64-NEXT: subl %edi, %esi 512; X64-NEXT: cmovael %esi, %eax 513; X64-NEXT: retq 514 %min = call i32 @llvm.umin.i32(i32 %a, i32 %b) 515 %max = call i32 @llvm.umax.i32(i32 %a, i32 %b) 516 %sub = sub i32 %max, %min 517 ret i32 %sub 518} 519 520define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind { 521; X86-LABEL: abd_minmax_i64: 522; X86: # %bb.0: 523; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 524; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 525; X86-NEXT: xorl %ecx, %ecx 526; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 527; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 528; X86-NEXT: sbbl %ecx, %ecx 529; X86-NEXT: xorl %ecx, %edx 530; X86-NEXT: xorl %ecx, %eax 531; X86-NEXT: subl %ecx, %eax 532; X86-NEXT: sbbl %ecx, %edx 533; X86-NEXT: retl 534; 535; X64-LABEL: abd_minmax_i64: 536; X64: # %bb.0: 537; X64-NEXT: movq %rdi, %rax 538; X64-NEXT: subq %rsi, %rax 539; X64-NEXT: subq %rdi, %rsi 540; X64-NEXT: cmovaeq %rsi, %rax 541; X64-NEXT: retq 542 %min = call i64 @llvm.umin.i64(i64 %a, i64 %b) 543 %max = call i64 @llvm.umax.i64(i64 %a, i64 %b) 544 %sub = sub i64 %max, %min 545 ret i64 %sub 546} 547 548define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind { 549; X86-LABEL: abd_minmax_i128: 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), %edx 555; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 556; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 557; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 558; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 559; X86-NEXT: xorl %ebx, %ebx 560; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 561; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 562; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 563; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 564; X86-NEXT: sbbl %ebx, %ebx 565; X86-NEXT: xorl %ebx, %ecx 566; X86-NEXT: xorl %ebx, %edx 567; X86-NEXT: xorl %ebx, %esi 568; X86-NEXT: xorl %ebx, %edi 569; X86-NEXT: subl %ebx, %edi 570; X86-NEXT: sbbl %ebx, %esi 571; X86-NEXT: sbbl %ebx, %edx 572; X86-NEXT: sbbl %ebx, %ecx 573; X86-NEXT: movl %edi, (%eax) 574; X86-NEXT: movl %esi, 4(%eax) 575; X86-NEXT: movl %edx, 8(%eax) 576; X86-NEXT: movl %ecx, 12(%eax) 577; X86-NEXT: popl %esi 578; X86-NEXT: popl %edi 579; X86-NEXT: popl %ebx 580; X86-NEXT: retl $4 581; 582; X64-LABEL: abd_minmax_i128: 583; X64: # %bb.0: 584; X64-NEXT: movq %rdi, %rax 585; X64-NEXT: xorl %edi, %edi 586; X64-NEXT: subq %rdx, %rax 587; X64-NEXT: sbbq %rcx, %rsi 588; X64-NEXT: sbbq %rdi, %rdi 589; X64-NEXT: xorq %rdi, %rsi 590; X64-NEXT: xorq %rdi, %rax 591; X64-NEXT: subq %rdi, %rax 592; X64-NEXT: sbbq %rdi, %rsi 593; X64-NEXT: movq %rsi, %rdx 594; X64-NEXT: retq 595 %min = call i128 @llvm.umin.i128(i128 %a, i128 %b) 596 %max = call i128 @llvm.umax.i128(i128 %a, i128 %b) 597 %sub = sub i128 %max, %min 598 ret i128 %sub 599} 600 601; 602; select(icmp(a,b),sub(a,b),sub(b,a)) -> abdu(a,b) 603; 604 605define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind { 606; X86-LABEL: abd_cmp_i8: 607; X86: # %bb.0: 608; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 609; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 610; X86-NEXT: movl %ecx, %edx 611; X86-NEXT: subl %eax, %edx 612; X86-NEXT: subl %ecx, %eax 613; X86-NEXT: cmovbl %edx, %eax 614; X86-NEXT: # kill: def $al killed $al killed $eax 615; X86-NEXT: retl 616; 617; X64-LABEL: abd_cmp_i8: 618; X64: # %bb.0: 619; X64-NEXT: movzbl %dil, %eax 620; X64-NEXT: movzbl %sil, %ecx 621; X64-NEXT: movl %ecx, %edx 622; X64-NEXT: subl %eax, %edx 623; X64-NEXT: subl %ecx, %eax 624; X64-NEXT: cmovbl %edx, %eax 625; X64-NEXT: # kill: def $al killed $al killed $eax 626; X64-NEXT: retq 627 %cmp = icmp ugt i8 %a, %b 628 %ab = sub i8 %a, %b 629 %ba = sub i8 %b, %a 630 %sel = select i1 %cmp, i8 %ab, i8 %ba 631 ret i8 %sel 632} 633 634define i16 @abd_cmp_i16(i16 %a, i16 %b) nounwind { 635; X86-LABEL: abd_cmp_i16: 636; X86: # %bb.0: 637; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 638; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 639; X86-NEXT: movl %ecx, %edx 640; X86-NEXT: subl %eax, %edx 641; X86-NEXT: subl %ecx, %eax 642; X86-NEXT: cmovbl %edx, %eax 643; X86-NEXT: # kill: def $ax killed $ax killed $eax 644; X86-NEXT: retl 645; 646; X64-LABEL: abd_cmp_i16: 647; X64: # %bb.0: 648; X64-NEXT: movzwl %si, %eax 649; X64-NEXT: movzwl %di, %ecx 650; X64-NEXT: movl %ecx, %edx 651; X64-NEXT: subl %eax, %edx 652; X64-NEXT: subl %ecx, %eax 653; X64-NEXT: cmovbl %edx, %eax 654; X64-NEXT: # kill: def $ax killed $ax killed $eax 655; X64-NEXT: retq 656 %cmp = icmp uge i16 %a, %b 657 %ab = sub i16 %a, %b 658 %ba = sub i16 %b, %a 659 %sel = select i1 %cmp, i16 %ab, i16 %ba 660 ret i16 %sel 661} 662 663define i32 @abd_cmp_i32(i32 %a, i32 %b) nounwind { 664; X86-LABEL: abd_cmp_i32: 665; X86: # %bb.0: 666; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 667; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 668; X86-NEXT: movl %ecx, %edx 669; X86-NEXT: subl %eax, %edx 670; X86-NEXT: subl %ecx, %eax 671; X86-NEXT: cmovbl %edx, %eax 672; X86-NEXT: retl 673; 674; X64-LABEL: abd_cmp_i32: 675; X64: # %bb.0: 676; X64-NEXT: movl %edi, %eax 677; X64-NEXT: subl %esi, %eax 678; X64-NEXT: subl %edi, %esi 679; X64-NEXT: cmovael %esi, %eax 680; X64-NEXT: retq 681 %cmp = icmp ult i32 %a, %b 682 %ab = sub i32 %a, %b 683 %ba = sub i32 %b, %a 684 %sel = select i1 %cmp, i32 %ba, i32 %ab 685 ret i32 %sel 686} 687 688define i64 @abd_cmp_i64(i64 %a, i64 %b) nounwind { 689; X86-LABEL: abd_cmp_i64: 690; X86: # %bb.0: 691; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 692; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 693; X86-NEXT: xorl %ecx, %ecx 694; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 695; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 696; X86-NEXT: sbbl %ecx, %ecx 697; X86-NEXT: xorl %ecx, %edx 698; X86-NEXT: xorl %ecx, %eax 699; X86-NEXT: subl %ecx, %eax 700; X86-NEXT: sbbl %ecx, %edx 701; X86-NEXT: retl 702; 703; X64-LABEL: abd_cmp_i64: 704; X64: # %bb.0: 705; X64-NEXT: movq %rdi, %rax 706; X64-NEXT: subq %rsi, %rax 707; X64-NEXT: subq %rdi, %rsi 708; X64-NEXT: cmovaeq %rsi, %rax 709; X64-NEXT: retq 710 %cmp = icmp uge i64 %a, %b 711 %ab = sub i64 %a, %b 712 %ba = sub i64 %b, %a 713 %sel = select i1 %cmp, i64 %ab, i64 %ba 714 ret i64 %sel 715} 716 717define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind { 718; X86-LABEL: abd_cmp_i128: 719; X86: # %bb.0: 720; X86-NEXT: pushl %ebx 721; X86-NEXT: pushl %edi 722; X86-NEXT: pushl %esi 723; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 724; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 725; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 726; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 727; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 728; X86-NEXT: xorl %ebx, %ebx 729; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 730; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 731; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 732; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 733; X86-NEXT: sbbl %ebx, %ebx 734; X86-NEXT: xorl %ebx, %ecx 735; X86-NEXT: xorl %ebx, %edx 736; X86-NEXT: xorl %ebx, %esi 737; X86-NEXT: xorl %ebx, %edi 738; X86-NEXT: subl %ebx, %edi 739; X86-NEXT: sbbl %ebx, %esi 740; X86-NEXT: sbbl %ebx, %edx 741; X86-NEXT: sbbl %ebx, %ecx 742; X86-NEXT: movl %edi, (%eax) 743; X86-NEXT: movl %esi, 4(%eax) 744; X86-NEXT: movl %edx, 8(%eax) 745; X86-NEXT: movl %ecx, 12(%eax) 746; X86-NEXT: popl %esi 747; X86-NEXT: popl %edi 748; X86-NEXT: popl %ebx 749; X86-NEXT: retl $4 750; 751; X64-LABEL: abd_cmp_i128: 752; X64: # %bb.0: 753; X64-NEXT: movq %rdi, %rax 754; X64-NEXT: xorl %edi, %edi 755; X64-NEXT: subq %rdx, %rax 756; X64-NEXT: sbbq %rcx, %rsi 757; X64-NEXT: sbbq %rdi, %rdi 758; X64-NEXT: xorq %rdi, %rsi 759; X64-NEXT: xorq %rdi, %rax 760; X64-NEXT: subq %rdi, %rax 761; X64-NEXT: sbbq %rdi, %rsi 762; X64-NEXT: movq %rsi, %rdx 763; X64-NEXT: retq 764 %cmp = icmp uge i128 %a, %b 765 %ab = sub i128 %a, %b 766 %ba = sub i128 %b, %a 767 %sel = select i1 %cmp, i128 %ab, i128 %ba 768 ret i128 %sel 769} 770 771; 772; sub(select(icmp(a,b),a,b),select(icmp(a,b),b,a)) -> abdu(a,b) 773; 774 775define i8 @abd_select_i8(i8 %a, i8 %b) nounwind { 776; X86-LABEL: abd_select_i8: 777; X86: # %bb.0: 778; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax 779; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 780; X86-NEXT: movl %ecx, %edx 781; X86-NEXT: subl %eax, %edx 782; X86-NEXT: subl %ecx, %eax 783; X86-NEXT: cmovbl %edx, %eax 784; X86-NEXT: # kill: def $al killed $al killed $eax 785; X86-NEXT: retl 786; 787; X64-LABEL: abd_select_i8: 788; X64: # %bb.0: 789; X64-NEXT: movzbl %sil, %eax 790; X64-NEXT: movzbl %dil, %ecx 791; X64-NEXT: movl %ecx, %edx 792; X64-NEXT: subl %eax, %edx 793; X64-NEXT: subl %ecx, %eax 794; X64-NEXT: cmovbl %edx, %eax 795; X64-NEXT: # kill: def $al killed $al killed $eax 796; X64-NEXT: retq 797 %cmp = icmp ult i8 %a, %b 798 %ab = select i1 %cmp, i8 %a, i8 %b 799 %ba = select i1 %cmp, i8 %b, i8 %a 800 %sub = sub i8 %ba, %ab 801 ret i8 %sub 802} 803 804define i16 @abd_select_i16(i16 %a, i16 %b) nounwind { 805; X86-LABEL: abd_select_i16: 806; X86: # %bb.0: 807; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 808; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx 809; X86-NEXT: movl %ecx, %edx 810; X86-NEXT: subl %eax, %edx 811; X86-NEXT: subl %ecx, %eax 812; X86-NEXT: cmovbl %edx, %eax 813; X86-NEXT: # kill: def $ax killed $ax killed $eax 814; X86-NEXT: retl 815; 816; X64-LABEL: abd_select_i16: 817; X64: # %bb.0: 818; X64-NEXT: movzwl %si, %eax 819; X64-NEXT: movzwl %di, %ecx 820; X64-NEXT: movl %ecx, %edx 821; X64-NEXT: subl %eax, %edx 822; X64-NEXT: subl %ecx, %eax 823; X64-NEXT: cmovbl %edx, %eax 824; X64-NEXT: # kill: def $ax killed $ax killed $eax 825; X64-NEXT: retq 826 %cmp = icmp ule i16 %a, %b 827 %ab = select i1 %cmp, i16 %a, i16 %b 828 %ba = select i1 %cmp, i16 %b, i16 %a 829 %sub = sub i16 %ba, %ab 830 ret i16 %sub 831} 832 833define i32 @abd_select_i32(i32 %a, i32 %b) nounwind { 834; X86-LABEL: abd_select_i32: 835; X86: # %bb.0: 836; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 837; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 838; X86-NEXT: movl %ecx, %edx 839; X86-NEXT: subl %eax, %edx 840; X86-NEXT: subl %ecx, %eax 841; X86-NEXT: cmovbl %edx, %eax 842; X86-NEXT: retl 843; 844; X64-LABEL: abd_select_i32: 845; X64: # %bb.0: 846; X64-NEXT: movl %edi, %eax 847; X64-NEXT: subl %esi, %eax 848; X64-NEXT: subl %edi, %esi 849; X64-NEXT: cmovael %esi, %eax 850; X64-NEXT: retq 851 %cmp = icmp ugt i32 %a, %b 852 %ab = select i1 %cmp, i32 %a, i32 %b 853 %ba = select i1 %cmp, i32 %b, i32 %a 854 %sub = sub i32 %ab, %ba 855 ret i32 %sub 856} 857 858define i64 @abd_select_i64(i64 %a, i64 %b) nounwind { 859; X86-LABEL: abd_select_i64: 860; X86: # %bb.0: 861; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 862; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 863; X86-NEXT: xorl %ecx, %ecx 864; X86-NEXT: subl {{[0-9]+}}(%esp), %eax 865; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 866; X86-NEXT: sbbl %ecx, %ecx 867; X86-NEXT: xorl %ecx, %edx 868; X86-NEXT: xorl %ecx, %eax 869; X86-NEXT: subl %ecx, %eax 870; X86-NEXT: sbbl %ecx, %edx 871; X86-NEXT: retl 872; 873; X64-LABEL: abd_select_i64: 874; X64: # %bb.0: 875; X64-NEXT: movq %rdi, %rax 876; X64-NEXT: subq %rsi, %rax 877; X64-NEXT: subq %rdi, %rsi 878; X64-NEXT: cmovaeq %rsi, %rax 879; X64-NEXT: retq 880 %cmp = icmp uge i64 %a, %b 881 %ab = select i1 %cmp, i64 %a, i64 %b 882 %ba = select i1 %cmp, i64 %b, i64 %a 883 %sub = sub i64 %ab, %ba 884 ret i64 %sub 885} 886 887define i128 @abd_select_i128(i128 %a, i128 %b) nounwind { 888; X86-LABEL: abd_select_i128: 889; X86: # %bb.0: 890; X86-NEXT: pushl %ebx 891; X86-NEXT: pushl %edi 892; X86-NEXT: pushl %esi 893; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 894; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 895; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 896; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 897; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 898; X86-NEXT: xorl %ebx, %ebx 899; X86-NEXT: subl {{[0-9]+}}(%esp), %edi 900; X86-NEXT: sbbl {{[0-9]+}}(%esp), %esi 901; X86-NEXT: sbbl {{[0-9]+}}(%esp), %edx 902; X86-NEXT: sbbl {{[0-9]+}}(%esp), %ecx 903; X86-NEXT: sbbl %ebx, %ebx 904; X86-NEXT: xorl %ebx, %ecx 905; X86-NEXT: xorl %ebx, %edx 906; X86-NEXT: xorl %ebx, %esi 907; X86-NEXT: xorl %ebx, %edi 908; X86-NEXT: subl %ebx, %edi 909; X86-NEXT: sbbl %ebx, %esi 910; X86-NEXT: sbbl %ebx, %edx 911; X86-NEXT: sbbl %ebx, %ecx 912; X86-NEXT: movl %edi, (%eax) 913; X86-NEXT: movl %esi, 4(%eax) 914; X86-NEXT: movl %edx, 8(%eax) 915; X86-NEXT: movl %ecx, 12(%eax) 916; X86-NEXT: popl %esi 917; X86-NEXT: popl %edi 918; X86-NEXT: popl %ebx 919; X86-NEXT: retl $4 920; 921; X64-LABEL: abd_select_i128: 922; X64: # %bb.0: 923; X64-NEXT: movq %rdi, %rax 924; X64-NEXT: xorl %edi, %edi 925; X64-NEXT: subq %rdx, %rax 926; X64-NEXT: sbbq %rcx, %rsi 927; X64-NEXT: sbbq %rdi, %rdi 928; X64-NEXT: xorq %rdi, %rsi 929; X64-NEXT: xorq %rdi, %rax 930; X64-NEXT: subq %rdi, %rax 931; X64-NEXT: sbbq %rdi, %rsi 932; X64-NEXT: movq %rsi, %rdx 933; X64-NEXT: retq 934 %cmp = icmp ult i128 %a, %b 935 %ab = select i1 %cmp, i128 %a, i128 %b 936 %ba = select i1 %cmp, i128 %b, i128 %a 937 %sub = sub i128 %ba, %ab 938 ret i128 %sub 939} 940 941declare i8 @llvm.abs.i8(i8, i1) 942declare i16 @llvm.abs.i16(i16, i1) 943declare i32 @llvm.abs.i32(i32, i1) 944declare i64 @llvm.abs.i64(i64, i1) 945declare i128 @llvm.abs.i128(i128, i1) 946 947declare i8 @llvm.umax.i8(i8, i8) 948declare i16 @llvm.umax.i16(i16, i16) 949declare i32 @llvm.umax.i32(i32, i32) 950declare i64 @llvm.umax.i64(i64, i64) 951 952declare i8 @llvm.umin.i8(i8, i8) 953declare i16 @llvm.umin.i16(i16, i16) 954declare i32 @llvm.umin.i32(i32, i32) 955declare i64 @llvm.umin.i64(i64, i64) 956