1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X64 4 5;==============================================================================; 6; the shift amount is negated (shiftbitwidth - shiftamt) 7;==============================================================================; 8 9; shift left 10;------------------------------------------------------------------------------; 11 12define i32 @reg32_shl_by_negated(i32 %val, i32 %shamt) nounwind { 13; X86-LABEL: reg32_shl_by_negated: 14; X86: # %bb.0: 15; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 16; X86-NEXT: xorl %ecx, %ecx 17; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 18; X86-NEXT: # kill: def $cl killed $cl killed $ecx 19; X86-NEXT: shll %cl, %eax 20; X86-NEXT: retl 21; 22; X64-LABEL: reg32_shl_by_negated: 23; X64: # %bb.0: 24; X64-NEXT: movl %esi, %ecx 25; X64-NEXT: movl %edi, %eax 26; X64-NEXT: negb %cl 27; X64-NEXT: # kill: def $cl killed $cl killed $ecx 28; X64-NEXT: shll %cl, %eax 29; X64-NEXT: retq 30 %negshamt = sub i32 32, %shamt 31 %shifted = shl i32 %val, %negshamt 32 ret i32 %shifted 33} 34define i32 @load32_shl_by_negated(ptr %valptr, i32 %shamt) nounwind { 35; X86-LABEL: load32_shl_by_negated: 36; X86: # %bb.0: 37; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 38; X86-NEXT: movl (%eax), %eax 39; X86-NEXT: xorl %ecx, %ecx 40; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 41; X86-NEXT: # kill: def $cl killed $cl killed $ecx 42; X86-NEXT: shll %cl, %eax 43; X86-NEXT: retl 44; 45; X64-LABEL: load32_shl_by_negated: 46; X64: # %bb.0: 47; X64-NEXT: movl %esi, %ecx 48; X64-NEXT: movl (%rdi), %eax 49; X64-NEXT: negb %cl 50; X64-NEXT: # kill: def $cl killed $cl killed $ecx 51; X64-NEXT: shll %cl, %eax 52; X64-NEXT: retq 53 %val = load i32, ptr %valptr 54 %negshamt = sub i32 32, %shamt 55 %shifted = shl i32 %val, %negshamt 56 ret i32 %shifted 57} 58define void @store32_shl_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind { 59; X86-LABEL: store32_shl_by_negated: 60; X86: # %bb.0: 61; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 62; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 63; X86-NEXT: xorl %ecx, %ecx 64; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 65; X86-NEXT: # kill: def $cl killed $cl killed $ecx 66; X86-NEXT: shll %cl, %edx 67; X86-NEXT: movl %edx, (%eax) 68; X86-NEXT: retl 69; 70; X64-LABEL: store32_shl_by_negated: 71; X64: # %bb.0: 72; X64-NEXT: movl %edx, %ecx 73; X64-NEXT: negb %cl 74; X64-NEXT: # kill: def $cl killed $cl killed $ecx 75; X64-NEXT: shll %cl, %edi 76; X64-NEXT: movl %edi, (%rsi) 77; X64-NEXT: retq 78 %negshamt = sub i32 32, %shamt 79 %shifted = shl i32 %val, %negshamt 80 store i32 %shifted, ptr %dstptr 81 ret void 82} 83define void @modify32_shl_by_negated(ptr %valptr, i32 %shamt) nounwind { 84; X86-LABEL: modify32_shl_by_negated: 85; X86: # %bb.0: 86; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 87; X86-NEXT: movb $32, %cl 88; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 89; X86-NEXT: shll %cl, (%eax) 90; X86-NEXT: retl 91; 92; X64-LABEL: modify32_shl_by_negated: 93; X64: # %bb.0: 94; X64-NEXT: movb $32, %cl 95; X64-NEXT: subb %sil, %cl 96; X64-NEXT: shll %cl, (%rdi) 97; X64-NEXT: retq 98 %val = load i32, ptr %valptr 99 %negshamt = sub i32 32, %shamt 100 %shifted = shl i32 %val, %negshamt 101 store i32 %shifted, ptr %valptr 102 ret void 103} 104 105define i64 @reg64_shl_by_negated(i64 %val, i64 %shamt) nounwind { 106; X86-LABEL: reg64_shl_by_negated: 107; X86: # %bb.0: 108; X86-NEXT: pushl %esi 109; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 110; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 111; X86-NEXT: movb $64, %cl 112; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 113; X86-NEXT: movl %esi, %eax 114; X86-NEXT: shll %cl, %eax 115; X86-NEXT: shldl %cl, %esi, %edx 116; X86-NEXT: testb $32, %cl 117; X86-NEXT: je .LBB4_2 118; X86-NEXT: # %bb.1: 119; X86-NEXT: movl %eax, %edx 120; X86-NEXT: xorl %eax, %eax 121; X86-NEXT: .LBB4_2: 122; X86-NEXT: popl %esi 123; X86-NEXT: retl 124; 125; X64-LABEL: reg64_shl_by_negated: 126; X64: # %bb.0: 127; X64-NEXT: movq %rsi, %rcx 128; X64-NEXT: movq %rdi, %rax 129; X64-NEXT: negb %cl 130; X64-NEXT: # kill: def $cl killed $cl killed $rcx 131; X64-NEXT: shlq %cl, %rax 132; X64-NEXT: retq 133 %negshamt = sub i64 64, %shamt 134 %shifted = shl i64 %val, %negshamt 135 ret i64 %shifted 136} 137define i64 @load64_shl_by_negated(ptr %valptr, i64 %shamt) nounwind { 138; X86-LABEL: load64_shl_by_negated: 139; X86: # %bb.0: 140; X86-NEXT: pushl %esi 141; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 142; X86-NEXT: movl (%eax), %esi 143; X86-NEXT: movl 4(%eax), %edx 144; X86-NEXT: movb $64, %cl 145; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 146; X86-NEXT: movl %esi, %eax 147; X86-NEXT: shll %cl, %eax 148; X86-NEXT: shldl %cl, %esi, %edx 149; X86-NEXT: testb $32, %cl 150; X86-NEXT: je .LBB5_2 151; X86-NEXT: # %bb.1: 152; X86-NEXT: movl %eax, %edx 153; X86-NEXT: xorl %eax, %eax 154; X86-NEXT: .LBB5_2: 155; X86-NEXT: popl %esi 156; X86-NEXT: retl 157; 158; X64-LABEL: load64_shl_by_negated: 159; X64: # %bb.0: 160; X64-NEXT: movq %rsi, %rcx 161; X64-NEXT: movq (%rdi), %rax 162; X64-NEXT: negb %cl 163; X64-NEXT: # kill: def $cl killed $cl killed $rcx 164; X64-NEXT: shlq %cl, %rax 165; X64-NEXT: retq 166 %val = load i64, ptr %valptr 167 %negshamt = sub i64 64, %shamt 168 %shifted = shl i64 %val, %negshamt 169 ret i64 %shifted 170} 171define void @store64_shl_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind { 172; X86-LABEL: store64_shl_by_negated: 173; X86: # %bb.0: 174; X86-NEXT: pushl %edi 175; X86-NEXT: pushl %esi 176; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 177; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 178; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 179; X86-NEXT: movb $64, %cl 180; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 181; X86-NEXT: movl %edi, %esi 182; X86-NEXT: shll %cl, %esi 183; X86-NEXT: shldl %cl, %edi, %edx 184; X86-NEXT: testb $32, %cl 185; X86-NEXT: je .LBB6_2 186; X86-NEXT: # %bb.1: 187; X86-NEXT: movl %esi, %edx 188; X86-NEXT: xorl %esi, %esi 189; X86-NEXT: .LBB6_2: 190; X86-NEXT: movl %edx, 4(%eax) 191; X86-NEXT: movl %esi, (%eax) 192; X86-NEXT: popl %esi 193; X86-NEXT: popl %edi 194; X86-NEXT: retl 195; 196; X64-LABEL: store64_shl_by_negated: 197; X64: # %bb.0: 198; X64-NEXT: movq %rdx, %rcx 199; X64-NEXT: negb %cl 200; X64-NEXT: # kill: def $cl killed $cl killed $rcx 201; X64-NEXT: shlq %cl, %rdi 202; X64-NEXT: movq %rdi, (%rsi) 203; X64-NEXT: retq 204 %negshamt = sub i64 64, %shamt 205 %shifted = shl i64 %val, %negshamt 206 store i64 %shifted, ptr %dstptr 207 ret void 208} 209define void @modify64_shl_by_negated(ptr %valptr, i64 %shamt) nounwind { 210; X86-LABEL: modify64_shl_by_negated: 211; X86: # %bb.0: 212; X86-NEXT: pushl %edi 213; X86-NEXT: pushl %esi 214; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 215; X86-NEXT: movl (%eax), %edi 216; X86-NEXT: movl 4(%eax), %edx 217; X86-NEXT: movb $64, %cl 218; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 219; X86-NEXT: movl %edi, %esi 220; X86-NEXT: shll %cl, %esi 221; X86-NEXT: shldl %cl, %edi, %edx 222; X86-NEXT: testb $32, %cl 223; X86-NEXT: je .LBB7_2 224; X86-NEXT: # %bb.1: 225; X86-NEXT: movl %esi, %edx 226; X86-NEXT: xorl %esi, %esi 227; X86-NEXT: .LBB7_2: 228; X86-NEXT: movl %esi, (%eax) 229; X86-NEXT: movl %edx, 4(%eax) 230; X86-NEXT: popl %esi 231; X86-NEXT: popl %edi 232; X86-NEXT: retl 233; 234; X64-LABEL: modify64_shl_by_negated: 235; X64: # %bb.0: 236; X64-NEXT: movb $64, %cl 237; X64-NEXT: subb %sil, %cl 238; X64-NEXT: shlq %cl, (%rdi) 239; X64-NEXT: retq 240 %val = load i64, ptr %valptr 241 %negshamt = sub i64 64, %shamt 242 %shifted = shl i64 %val, %negshamt 243 store i64 %shifted, ptr %valptr 244 ret void 245} 246 247; logical shift right 248;------------------------------------------------------------------------------; 249 250define i32 @reg32_lshr_by_negated(i32 %val, i32 %shamt) nounwind { 251; X86-LABEL: reg32_lshr_by_negated: 252; X86: # %bb.0: 253; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 254; X86-NEXT: xorl %ecx, %ecx 255; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 256; X86-NEXT: # kill: def $cl killed $cl killed $ecx 257; X86-NEXT: shrl %cl, %eax 258; X86-NEXT: retl 259; 260; X64-LABEL: reg32_lshr_by_negated: 261; X64: # %bb.0: 262; X64-NEXT: movl %esi, %ecx 263; X64-NEXT: movl %edi, %eax 264; X64-NEXT: negb %cl 265; X64-NEXT: # kill: def $cl killed $cl killed $ecx 266; X64-NEXT: shrl %cl, %eax 267; X64-NEXT: retq 268 %negshamt = sub i32 32, %shamt 269 %shifted = lshr i32 %val, %negshamt 270 ret i32 %shifted 271} 272define i32 @load32_lshr_by_negated(ptr %valptr, i32 %shamt) nounwind { 273; X86-LABEL: load32_lshr_by_negated: 274; X86: # %bb.0: 275; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 276; X86-NEXT: movl (%eax), %eax 277; X86-NEXT: xorl %ecx, %ecx 278; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 279; X86-NEXT: # kill: def $cl killed $cl killed $ecx 280; X86-NEXT: shrl %cl, %eax 281; X86-NEXT: retl 282; 283; X64-LABEL: load32_lshr_by_negated: 284; X64: # %bb.0: 285; X64-NEXT: movl %esi, %ecx 286; X64-NEXT: movl (%rdi), %eax 287; X64-NEXT: negb %cl 288; X64-NEXT: # kill: def $cl killed $cl killed $ecx 289; X64-NEXT: shrl %cl, %eax 290; X64-NEXT: retq 291 %val = load i32, ptr %valptr 292 %negshamt = sub i32 32, %shamt 293 %shifted = lshr i32 %val, %negshamt 294 ret i32 %shifted 295} 296define void @store32_lshr_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind { 297; X86-LABEL: store32_lshr_by_negated: 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: subb {{[0-9]+}}(%esp), %cl 303; X86-NEXT: # kill: def $cl killed $cl killed $ecx 304; X86-NEXT: shrl %cl, %edx 305; X86-NEXT: movl %edx, (%eax) 306; X86-NEXT: retl 307; 308; X64-LABEL: store32_lshr_by_negated: 309; X64: # %bb.0: 310; X64-NEXT: movl %edx, %ecx 311; X64-NEXT: negb %cl 312; X64-NEXT: # kill: def $cl killed $cl killed $ecx 313; X64-NEXT: shrl %cl, %edi 314; X64-NEXT: movl %edi, (%rsi) 315; X64-NEXT: retq 316 %negshamt = sub i32 32, %shamt 317 %shifted = lshr i32 %val, %negshamt 318 store i32 %shifted, ptr %dstptr 319 ret void 320} 321define void @modify32_lshr_by_negated(ptr %valptr, i32 %shamt) nounwind { 322; X86-LABEL: modify32_lshr_by_negated: 323; X86: # %bb.0: 324; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 325; X86-NEXT: movb $32, %cl 326; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 327; X86-NEXT: shrl %cl, (%eax) 328; X86-NEXT: retl 329; 330; X64-LABEL: modify32_lshr_by_negated: 331; X64: # %bb.0: 332; X64-NEXT: movb $32, %cl 333; X64-NEXT: subb %sil, %cl 334; X64-NEXT: shrl %cl, (%rdi) 335; X64-NEXT: retq 336 %val = load i32, ptr %valptr 337 %negshamt = sub i32 32, %shamt 338 %shifted = lshr i32 %val, %negshamt 339 store i32 %shifted, ptr %valptr 340 ret void 341} 342 343define i64 @reg64_lshr_by_negated(i64 %val, i64 %shamt) nounwind { 344; X86-LABEL: reg64_lshr_by_negated: 345; X86: # %bb.0: 346; X86-NEXT: pushl %esi 347; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 348; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 349; X86-NEXT: movb $64, %cl 350; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 351; X86-NEXT: movl %esi, %edx 352; X86-NEXT: shrl %cl, %edx 353; X86-NEXT: shrdl %cl, %esi, %eax 354; X86-NEXT: testb $32, %cl 355; X86-NEXT: je .LBB12_2 356; X86-NEXT: # %bb.1: 357; X86-NEXT: movl %edx, %eax 358; X86-NEXT: xorl %edx, %edx 359; X86-NEXT: .LBB12_2: 360; X86-NEXT: popl %esi 361; X86-NEXT: retl 362; 363; X64-LABEL: reg64_lshr_by_negated: 364; X64: # %bb.0: 365; X64-NEXT: movq %rsi, %rcx 366; X64-NEXT: movq %rdi, %rax 367; X64-NEXT: negb %cl 368; X64-NEXT: # kill: def $cl killed $cl killed $rcx 369; X64-NEXT: shrq %cl, %rax 370; X64-NEXT: retq 371 %negshamt = sub i64 64, %shamt 372 %shifted = lshr i64 %val, %negshamt 373 ret i64 %shifted 374} 375define i64 @load64_lshr_by_negated(ptr %valptr, i64 %shamt) nounwind { 376; X86-LABEL: load64_lshr_by_negated: 377; X86: # %bb.0: 378; X86-NEXT: pushl %esi 379; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 380; X86-NEXT: movl (%ecx), %eax 381; X86-NEXT: movl 4(%ecx), %esi 382; X86-NEXT: movb $64, %cl 383; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 384; X86-NEXT: movl %esi, %edx 385; X86-NEXT: shrl %cl, %edx 386; X86-NEXT: shrdl %cl, %esi, %eax 387; X86-NEXT: testb $32, %cl 388; X86-NEXT: je .LBB13_2 389; X86-NEXT: # %bb.1: 390; X86-NEXT: movl %edx, %eax 391; X86-NEXT: xorl %edx, %edx 392; X86-NEXT: .LBB13_2: 393; X86-NEXT: popl %esi 394; X86-NEXT: retl 395; 396; X64-LABEL: load64_lshr_by_negated: 397; X64: # %bb.0: 398; X64-NEXT: movq %rsi, %rcx 399; X64-NEXT: movq (%rdi), %rax 400; X64-NEXT: negb %cl 401; X64-NEXT: # kill: def $cl killed $cl killed $rcx 402; X64-NEXT: shrq %cl, %rax 403; X64-NEXT: retq 404 %val = load i64, ptr %valptr 405 %negshamt = sub i64 64, %shamt 406 %shifted = lshr i64 %val, %negshamt 407 ret i64 %shifted 408} 409define void @store64_lshr_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind { 410; X86-LABEL: store64_lshr_by_negated: 411; X86: # %bb.0: 412; X86-NEXT: pushl %edi 413; X86-NEXT: pushl %esi 414; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 415; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 416; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 417; X86-NEXT: movb $64, %cl 418; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 419; X86-NEXT: movl %edi, %esi 420; X86-NEXT: shrl %cl, %esi 421; X86-NEXT: shrdl %cl, %edi, %edx 422; X86-NEXT: testb $32, %cl 423; X86-NEXT: je .LBB14_2 424; X86-NEXT: # %bb.1: 425; X86-NEXT: movl %esi, %edx 426; X86-NEXT: xorl %esi, %esi 427; X86-NEXT: .LBB14_2: 428; X86-NEXT: movl %esi, 4(%eax) 429; X86-NEXT: movl %edx, (%eax) 430; X86-NEXT: popl %esi 431; X86-NEXT: popl %edi 432; X86-NEXT: retl 433; 434; X64-LABEL: store64_lshr_by_negated: 435; X64: # %bb.0: 436; X64-NEXT: movq %rdx, %rcx 437; X64-NEXT: negb %cl 438; X64-NEXT: # kill: def $cl killed $cl killed $rcx 439; X64-NEXT: shrq %cl, %rdi 440; X64-NEXT: movq %rdi, (%rsi) 441; X64-NEXT: retq 442 %negshamt = sub i64 64, %shamt 443 %shifted = lshr i64 %val, %negshamt 444 store i64 %shifted, ptr %dstptr 445 ret void 446} 447define void @modify64_lshr_by_negated(ptr %valptr, i64 %shamt) nounwind { 448; X86-LABEL: modify64_lshr_by_negated: 449; X86: # %bb.0: 450; X86-NEXT: pushl %edi 451; X86-NEXT: pushl %esi 452; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 453; X86-NEXT: movl (%eax), %edx 454; X86-NEXT: movl 4(%eax), %edi 455; X86-NEXT: movb $64, %cl 456; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 457; X86-NEXT: movl %edi, %esi 458; X86-NEXT: shrl %cl, %esi 459; X86-NEXT: shrdl %cl, %edi, %edx 460; X86-NEXT: testb $32, %cl 461; X86-NEXT: je .LBB15_2 462; X86-NEXT: # %bb.1: 463; X86-NEXT: movl %esi, %edx 464; X86-NEXT: xorl %esi, %esi 465; X86-NEXT: .LBB15_2: 466; X86-NEXT: movl %edx, (%eax) 467; X86-NEXT: movl %esi, 4(%eax) 468; X86-NEXT: popl %esi 469; X86-NEXT: popl %edi 470; X86-NEXT: retl 471; 472; X64-LABEL: modify64_lshr_by_negated: 473; X64: # %bb.0: 474; X64-NEXT: movb $64, %cl 475; X64-NEXT: subb %sil, %cl 476; X64-NEXT: shrq %cl, (%rdi) 477; X64-NEXT: retq 478 %val = load i64, ptr %valptr 479 %negshamt = sub i64 64, %shamt 480 %shifted = lshr i64 %val, %negshamt 481 store i64 %shifted, ptr %valptr 482 ret void 483} 484 485; arithmetic shift right 486;------------------------------------------------------------------------------; 487 488define i32 @reg32_ashr_by_negated(i32 %val, i32 %shamt) nounwind { 489; X86-LABEL: reg32_ashr_by_negated: 490; X86: # %bb.0: 491; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 492; X86-NEXT: xorl %ecx, %ecx 493; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 494; X86-NEXT: # kill: def $cl killed $cl killed $ecx 495; X86-NEXT: sarl %cl, %eax 496; X86-NEXT: retl 497; 498; X64-LABEL: reg32_ashr_by_negated: 499; X64: # %bb.0: 500; X64-NEXT: movl %esi, %ecx 501; X64-NEXT: movl %edi, %eax 502; X64-NEXT: negb %cl 503; X64-NEXT: # kill: def $cl killed $cl killed $ecx 504; X64-NEXT: sarl %cl, %eax 505; X64-NEXT: retq 506 %negshamt = sub i32 32, %shamt 507 %shifted = ashr i32 %val, %negshamt 508 ret i32 %shifted 509} 510define i32 @load32_ashr_by_negated(ptr %valptr, i32 %shamt) nounwind { 511; X86-LABEL: load32_ashr_by_negated: 512; X86: # %bb.0: 513; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 514; X86-NEXT: movl (%eax), %eax 515; X86-NEXT: xorl %ecx, %ecx 516; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 517; X86-NEXT: # kill: def $cl killed $cl killed $ecx 518; X86-NEXT: sarl %cl, %eax 519; X86-NEXT: retl 520; 521; X64-LABEL: load32_ashr_by_negated: 522; X64: # %bb.0: 523; X64-NEXT: movl %esi, %ecx 524; X64-NEXT: movl (%rdi), %eax 525; X64-NEXT: negb %cl 526; X64-NEXT: # kill: def $cl killed $cl killed $ecx 527; X64-NEXT: sarl %cl, %eax 528; X64-NEXT: retq 529 %val = load i32, ptr %valptr 530 %negshamt = sub i32 32, %shamt 531 %shifted = ashr i32 %val, %negshamt 532 ret i32 %shifted 533} 534define void @store32_ashr_by_negated(i32 %val, ptr %dstptr, i32 %shamt) nounwind { 535; X86-LABEL: store32_ashr_by_negated: 536; X86: # %bb.0: 537; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 538; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 539; X86-NEXT: xorl %ecx, %ecx 540; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 541; X86-NEXT: # kill: def $cl killed $cl killed $ecx 542; X86-NEXT: sarl %cl, %edx 543; X86-NEXT: movl %edx, (%eax) 544; X86-NEXT: retl 545; 546; X64-LABEL: store32_ashr_by_negated: 547; X64: # %bb.0: 548; X64-NEXT: movl %edx, %ecx 549; X64-NEXT: negb %cl 550; X64-NEXT: # kill: def $cl killed $cl killed $ecx 551; X64-NEXT: sarl %cl, %edi 552; X64-NEXT: movl %edi, (%rsi) 553; X64-NEXT: retq 554 %negshamt = sub i32 32, %shamt 555 %shifted = ashr i32 %val, %negshamt 556 store i32 %shifted, ptr %dstptr 557 ret void 558} 559define void @modify32_ashr_by_negated(ptr %valptr, i32 %shamt) nounwind { 560; X86-LABEL: modify32_ashr_by_negated: 561; X86: # %bb.0: 562; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 563; X86-NEXT: movb $32, %cl 564; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 565; X86-NEXT: sarl %cl, (%eax) 566; X86-NEXT: retl 567; 568; X64-LABEL: modify32_ashr_by_negated: 569; X64: # %bb.0: 570; X64-NEXT: movb $32, %cl 571; X64-NEXT: subb %sil, %cl 572; X64-NEXT: sarl %cl, (%rdi) 573; X64-NEXT: retq 574 %val = load i32, ptr %valptr 575 %negshamt = sub i32 32, %shamt 576 %shifted = ashr i32 %val, %negshamt 577 store i32 %shifted, ptr %valptr 578 ret void 579} 580 581define i64 @reg64_ashr_by_negated(i64 %val, i64 %shamt) nounwind { 582; X86-LABEL: reg64_ashr_by_negated: 583; X86: # %bb.0: 584; X86-NEXT: pushl %esi 585; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 586; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 587; X86-NEXT: movb $64, %cl 588; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 589; X86-NEXT: movl %esi, %edx 590; X86-NEXT: sarl %cl, %edx 591; X86-NEXT: shrdl %cl, %esi, %eax 592; X86-NEXT: testb $32, %cl 593; X86-NEXT: je .LBB20_2 594; X86-NEXT: # %bb.1: 595; X86-NEXT: sarl $31, %esi 596; X86-NEXT: movl %edx, %eax 597; X86-NEXT: movl %esi, %edx 598; X86-NEXT: .LBB20_2: 599; X86-NEXT: popl %esi 600; X86-NEXT: retl 601; 602; X64-LABEL: reg64_ashr_by_negated: 603; X64: # %bb.0: 604; X64-NEXT: movq %rsi, %rcx 605; X64-NEXT: movq %rdi, %rax 606; X64-NEXT: negb %cl 607; X64-NEXT: # kill: def $cl killed $cl killed $rcx 608; X64-NEXT: sarq %cl, %rax 609; X64-NEXT: retq 610 %negshamt = sub i64 64, %shamt 611 %shifted = ashr i64 %val, %negshamt 612 ret i64 %shifted 613} 614define i64 @load64_ashr_by_negated(ptr %valptr, i64 %shamt) nounwind { 615; X86-LABEL: load64_ashr_by_negated: 616; X86: # %bb.0: 617; X86-NEXT: pushl %esi 618; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 619; X86-NEXT: movl (%ecx), %eax 620; X86-NEXT: movl 4(%ecx), %esi 621; X86-NEXT: movb $64, %cl 622; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 623; X86-NEXT: movl %esi, %edx 624; X86-NEXT: sarl %cl, %edx 625; X86-NEXT: shrdl %cl, %esi, %eax 626; X86-NEXT: testb $32, %cl 627; X86-NEXT: je .LBB21_2 628; X86-NEXT: # %bb.1: 629; X86-NEXT: sarl $31, %esi 630; X86-NEXT: movl %edx, %eax 631; X86-NEXT: movl %esi, %edx 632; X86-NEXT: .LBB21_2: 633; X86-NEXT: popl %esi 634; X86-NEXT: retl 635; 636; X64-LABEL: load64_ashr_by_negated: 637; X64: # %bb.0: 638; X64-NEXT: movq %rsi, %rcx 639; X64-NEXT: movq (%rdi), %rax 640; X64-NEXT: negb %cl 641; X64-NEXT: # kill: def $cl killed $cl killed $rcx 642; X64-NEXT: sarq %cl, %rax 643; X64-NEXT: retq 644 %val = load i64, ptr %valptr 645 %negshamt = sub i64 64, %shamt 646 %shifted = ashr i64 %val, %negshamt 647 ret i64 %shifted 648} 649define void @store64_ashr_by_negated(i64 %val, ptr %dstptr, i64 %shamt) nounwind { 650; X86-LABEL: store64_ashr_by_negated: 651; X86: # %bb.0: 652; X86-NEXT: pushl %edi 653; X86-NEXT: pushl %esi 654; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 655; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 656; X86-NEXT: movl {{[0-9]+}}(%esp), %edi 657; X86-NEXT: movb $64, %cl 658; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 659; X86-NEXT: movl %edi, %esi 660; X86-NEXT: sarl %cl, %esi 661; X86-NEXT: shrdl %cl, %edi, %edx 662; X86-NEXT: testb $32, %cl 663; X86-NEXT: je .LBB22_2 664; X86-NEXT: # %bb.1: 665; X86-NEXT: sarl $31, %edi 666; X86-NEXT: movl %esi, %edx 667; X86-NEXT: movl %edi, %esi 668; X86-NEXT: .LBB22_2: 669; X86-NEXT: movl %esi, 4(%eax) 670; X86-NEXT: movl %edx, (%eax) 671; X86-NEXT: popl %esi 672; X86-NEXT: popl %edi 673; X86-NEXT: retl 674; 675; X64-LABEL: store64_ashr_by_negated: 676; X64: # %bb.0: 677; X64-NEXT: movq %rdx, %rcx 678; X64-NEXT: negb %cl 679; X64-NEXT: # kill: def $cl killed $cl killed $rcx 680; X64-NEXT: sarq %cl, %rdi 681; X64-NEXT: movq %rdi, (%rsi) 682; X64-NEXT: retq 683 %negshamt = sub i64 64, %shamt 684 %shifted = ashr i64 %val, %negshamt 685 store i64 %shifted, ptr %dstptr 686 ret void 687} 688define void @modify64_ashr_by_negated(ptr %valptr, i64 %shamt) nounwind { 689; X86-LABEL: modify64_ashr_by_negated: 690; X86: # %bb.0: 691; X86-NEXT: pushl %edi 692; X86-NEXT: pushl %esi 693; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 694; X86-NEXT: movl (%eax), %edx 695; X86-NEXT: movl 4(%eax), %edi 696; X86-NEXT: movb $64, %cl 697; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 698; X86-NEXT: movl %edi, %esi 699; X86-NEXT: sarl %cl, %esi 700; X86-NEXT: shrdl %cl, %edi, %edx 701; X86-NEXT: testb $32, %cl 702; X86-NEXT: je .LBB23_2 703; X86-NEXT: # %bb.1: 704; X86-NEXT: sarl $31, %edi 705; X86-NEXT: movl %esi, %edx 706; X86-NEXT: movl %edi, %esi 707; X86-NEXT: .LBB23_2: 708; X86-NEXT: movl %edx, (%eax) 709; X86-NEXT: movl %esi, 4(%eax) 710; X86-NEXT: popl %esi 711; X86-NEXT: popl %edi 712; X86-NEXT: retl 713; 714; X64-LABEL: modify64_ashr_by_negated: 715; X64: # %bb.0: 716; X64-NEXT: movb $64, %cl 717; X64-NEXT: subb %sil, %cl 718; X64-NEXT: sarq %cl, (%rdi) 719; X64-NEXT: retq 720 %val = load i64, ptr %valptr 721 %negshamt = sub i64 64, %shamt 722 %shifted = ashr i64 %val, %negshamt 723 store i64 %shifted, ptr %valptr 724 ret void 725} 726 727;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||; 728; next let's only test simple reg pattern, and only lshr. 729;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||; 730 731;==============================================================================; 732; subtraction from negated shift amount 733 734define i32 @reg32_lshr_by_sub_from_negated(i32 %val, i32 %a, i32 %b) nounwind { 735; X86-LABEL: reg32_lshr_by_sub_from_negated: 736; X86: # %bb.0: 737; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 738; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 739; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 740; X86-NEXT: negb %cl 741; X86-NEXT: # kill: def $cl killed $cl killed $ecx 742; X86-NEXT: shrl %cl, %eax 743; X86-NEXT: retl 744; 745; X64-LABEL: reg32_lshr_by_sub_from_negated: 746; X64: # %bb.0: 747; X64-NEXT: # kill: def $edx killed $edx def $rdx 748; X64-NEXT: # kill: def $esi killed $esi def $rsi 749; X64-NEXT: movl %edi, %eax 750; X64-NEXT: leal (%rsi,%rdx), %ecx 751; X64-NEXT: negb %cl 752; X64-NEXT: # kill: def $cl killed $cl killed $ecx 753; X64-NEXT: shrl %cl, %eax 754; X64-NEXT: retq 755 %nega = sub i32 32, %a 756 %negasubb = sub i32 %nega, %b 757 %shifted = lshr i32 %val, %negasubb 758 ret i32 %shifted 759} 760define i64 @reg64_lshr_by_sub_from_negated(i64 %val, i64 %a, i64 %b) nounwind { 761; X86-LABEL: reg64_lshr_by_sub_from_negated: 762; X86: # %bb.0: 763; X86-NEXT: pushl %esi 764; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 765; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 766; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 767; X86-NEXT: addl {{[0-9]+}}(%esp), %edx 768; X86-NEXT: movb $64, %cl 769; X86-NEXT: subb %dl, %cl 770; X86-NEXT: movl %esi, %edx 771; X86-NEXT: shrl %cl, %edx 772; X86-NEXT: shrdl %cl, %esi, %eax 773; X86-NEXT: testb $32, %cl 774; X86-NEXT: je .LBB25_2 775; X86-NEXT: # %bb.1: 776; X86-NEXT: movl %edx, %eax 777; X86-NEXT: xorl %edx, %edx 778; X86-NEXT: .LBB25_2: 779; X86-NEXT: popl %esi 780; X86-NEXT: retl 781; 782; X64-LABEL: reg64_lshr_by_sub_from_negated: 783; X64: # %bb.0: 784; X64-NEXT: movq %rdi, %rax 785; X64-NEXT: leal (%rdx,%rsi), %ecx 786; X64-NEXT: negb %cl 787; X64-NEXT: # kill: def $cl killed $cl killed $ecx 788; X64-NEXT: shrq %cl, %rax 789; X64-NEXT: retq 790 %nega = sub i64 64, %a 791 %negasubb = sub i64 %nega, %b 792 %shifted = lshr i64 %val, %negasubb 793 ret i64 %shifted 794} 795 796;==============================================================================; 797; subtraction of negated shift amount 798 799define i32 @reg32_lshr_by_sub_of_negated(i32 %val, i32 %a, i32 %b) nounwind { 800; X86-LABEL: reg32_lshr_by_sub_of_negated: 801; X86: # %bb.0: 802; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 803; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 804; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 805; X86-NEXT: # kill: def $cl killed $cl killed $ecx 806; X86-NEXT: shrl %cl, %eax 807; X86-NEXT: retl 808; 809; X64-LABEL: reg32_lshr_by_sub_of_negated: 810; X64: # %bb.0: 811; X64-NEXT: # kill: def $edx killed $edx def $rdx 812; X64-NEXT: # kill: def $esi killed $esi def $rsi 813; X64-NEXT: movl %edi, %eax 814; X64-NEXT: leal (%rsi,%rdx), %ecx 815; X64-NEXT: # kill: def $cl killed $cl killed $ecx 816; X64-NEXT: shrl %cl, %eax 817; X64-NEXT: retq 818 %nega = sub i32 32, %a 819 %negasubb = sub i32 %b, %nega 820 %shifted = lshr i32 %val, %negasubb 821 ret i32 %shifted 822} 823define i64 @reg64_lshr_by_sub_of_negated(i64 %val, i64 %a, i64 %b) nounwind { 824; X86-LABEL: reg64_lshr_by_sub_of_negated: 825; X86: # %bb.0: 826; X86-NEXT: pushl %esi 827; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 828; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 829; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 830; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 831; X86-NEXT: addb $-64, %cl 832; X86-NEXT: movl %esi, %edx 833; X86-NEXT: shrl %cl, %edx 834; X86-NEXT: shrdl %cl, %esi, %eax 835; X86-NEXT: testb $32, %cl 836; X86-NEXT: je .LBB27_2 837; X86-NEXT: # %bb.1: 838; X86-NEXT: movl %edx, %eax 839; X86-NEXT: xorl %edx, %edx 840; X86-NEXT: .LBB27_2: 841; X86-NEXT: popl %esi 842; X86-NEXT: retl 843; 844; X64-LABEL: reg64_lshr_by_sub_of_negated: 845; X64: # %bb.0: 846; X64-NEXT: movq %rdi, %rax 847; X64-NEXT: leal (%rdx,%rsi), %ecx 848; X64-NEXT: # kill: def $cl killed $cl killed $ecx 849; X64-NEXT: shrq %cl, %rax 850; X64-NEXT: retq 851 %nega = sub i64 64, %a 852 %negasubb = sub i64 %b, %nega 853 %shifted = lshr i64 %val, %negasubb 854 ret i64 %shifted 855} 856 857;==============================================================================; 858; add to negated shift amount 859; 860 861define i32 @reg32_lshr_by_add_to_negated(i32 %val, i32 %a, i32 %b) nounwind { 862; X86-LABEL: reg32_lshr_by_add_to_negated: 863; X86: # %bb.0: 864; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 865; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 866; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 867; X86-NEXT: # kill: def $cl killed $cl killed $ecx 868; X86-NEXT: shrl %cl, %eax 869; X86-NEXT: retl 870; 871; X64-LABEL: reg32_lshr_by_add_to_negated: 872; X64: # %bb.0: 873; X64-NEXT: movl %edx, %ecx 874; X64-NEXT: movl %edi, %eax 875; X64-NEXT: subl %esi, %ecx 876; X64-NEXT: # kill: def $cl killed $cl killed $ecx 877; X64-NEXT: shrl %cl, %eax 878; X64-NEXT: retq 879 %nega = sub i32 32, %a 880 %negasubb = add i32 %nega, %b 881 %shifted = lshr i32 %val, %negasubb 882 ret i32 %shifted 883} 884define i64 @reg64_lshr_by_add_to_negated(i64 %val, i64 %a, i64 %b) nounwind { 885; X86-LABEL: reg64_lshr_by_add_to_negated: 886; X86: # %bb.0: 887; X86-NEXT: pushl %esi 888; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 889; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 890; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 891; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 892; X86-NEXT: addb $64, %cl 893; X86-NEXT: movl %esi, %edx 894; X86-NEXT: shrl %cl, %edx 895; X86-NEXT: shrdl %cl, %esi, %eax 896; X86-NEXT: testb $32, %cl 897; X86-NEXT: je .LBB29_2 898; X86-NEXT: # %bb.1: 899; X86-NEXT: movl %edx, %eax 900; X86-NEXT: xorl %edx, %edx 901; X86-NEXT: .LBB29_2: 902; X86-NEXT: popl %esi 903; X86-NEXT: retl 904; 905; X64-LABEL: reg64_lshr_by_add_to_negated: 906; X64: # %bb.0: 907; X64-NEXT: movq %rdx, %rcx 908; X64-NEXT: movq %rdi, %rax 909; X64-NEXT: subl %esi, %ecx 910; X64-NEXT: # kill: def $cl killed $cl killed $rcx 911; X64-NEXT: shrq %cl, %rax 912; X64-NEXT: retq 913 %nega = sub i64 64, %a 914 %negasubb = add i64 %nega, %b 915 %shifted = lshr i64 %val, %negasubb 916 ret i64 %shifted 917} 918 919;==============================================================================; 920; subtraction of negated shift amounts 921 922define i32 @reg32_lshr_by_sub_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind { 923; X86-LABEL: reg32_lshr_by_sub_of_negated_amts: 924; X86: # %bb.0: 925; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 926; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 927; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 928; X86-NEXT: # kill: def $cl killed $cl killed $ecx 929; X86-NEXT: shrl %cl, %eax 930; X86-NEXT: retl 931; 932; X64-LABEL: reg32_lshr_by_sub_of_negated_amts: 933; X64: # %bb.0: 934; X64-NEXT: movl %edx, %ecx 935; X64-NEXT: movl %edi, %eax 936; X64-NEXT: subl %esi, %ecx 937; X64-NEXT: # kill: def $cl killed $cl killed $ecx 938; X64-NEXT: shrl %cl, %eax 939; X64-NEXT: retq 940 %nega = sub i32 32, %a 941 %negb = sub i32 32, %b 942 %negasubnegb = sub i32 %nega, %negb 943 %shifted = lshr i32 %val, %negasubnegb 944 ret i32 %shifted 945} 946define i64 @reg64_lshr_by_sub_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind { 947; X86-LABEL: reg64_lshr_by_sub_of_negated_amts: 948; X86: # %bb.0: 949; X86-NEXT: pushl %esi 950; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 951; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 952; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 953; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 954; X86-NEXT: movl %esi, %edx 955; X86-NEXT: shrl %cl, %edx 956; X86-NEXT: shrdl %cl, %esi, %eax 957; X86-NEXT: testb $32, %cl 958; X86-NEXT: je .LBB31_2 959; X86-NEXT: # %bb.1: 960; X86-NEXT: movl %edx, %eax 961; X86-NEXT: xorl %edx, %edx 962; X86-NEXT: .LBB31_2: 963; X86-NEXT: popl %esi 964; X86-NEXT: retl 965; 966; X64-LABEL: reg64_lshr_by_sub_of_negated_amts: 967; X64: # %bb.0: 968; X64-NEXT: movq %rdx, %rcx 969; X64-NEXT: movq %rdi, %rax 970; X64-NEXT: subl %esi, %ecx 971; X64-NEXT: # kill: def $cl killed $cl killed $rcx 972; X64-NEXT: shrq %cl, %rax 973; X64-NEXT: retq 974 %nega = sub i64 64, %a 975 %negb = sub i64 64, %b 976 %negasubnegb = sub i64 %nega, %negb 977 %shifted = lshr i64 %val, %negasubnegb 978 ret i64 %shifted 979} 980 981;==============================================================================; 982; addition of negated shift amounts 983 984define i32 @reg32_lshr_by_add_of_negated_amts(i32 %val, i32 %a, i32 %b) nounwind { 985; X86-LABEL: reg32_lshr_by_add_of_negated_amts: 986; X86: # %bb.0: 987; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 988; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 989; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 990; X86-NEXT: negb %cl 991; X86-NEXT: # kill: def $cl killed $cl killed $ecx 992; X86-NEXT: shrl %cl, %eax 993; X86-NEXT: retl 994; 995; X64-LABEL: reg32_lshr_by_add_of_negated_amts: 996; X64: # %bb.0: 997; X64-NEXT: # kill: def $edx killed $edx def $rdx 998; X64-NEXT: # kill: def $esi killed $esi def $rsi 999; X64-NEXT: movl %edi, %eax 1000; X64-NEXT: leal (%rsi,%rdx), %ecx 1001; X64-NEXT: negb %cl 1002; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1003; X64-NEXT: shrl %cl, %eax 1004; X64-NEXT: retq 1005 %nega = sub i32 32, %a 1006 %negb = sub i32 32, %b 1007 %negasubnegb = add i32 %nega, %negb 1008 %shifted = lshr i32 %val, %negasubnegb 1009 ret i32 %shifted 1010} 1011define i64 @reg64_lshr_by_add_of_negated_amts(i64 %val, i64 %a, i64 %b) nounwind { 1012; X86-LABEL: reg64_lshr_by_add_of_negated_amts: 1013; X86: # %bb.0: 1014; X86-NEXT: pushl %esi 1015; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1016; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1017; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1018; X86-NEXT: addl {{[0-9]+}}(%esp), %edx 1019; X86-NEXT: movb $-128, %cl 1020; X86-NEXT: subb %dl, %cl 1021; X86-NEXT: movl %esi, %edx 1022; X86-NEXT: shrl %cl, %edx 1023; X86-NEXT: shrdl %cl, %esi, %eax 1024; X86-NEXT: testb $32, %cl 1025; X86-NEXT: je .LBB33_2 1026; X86-NEXT: # %bb.1: 1027; X86-NEXT: movl %edx, %eax 1028; X86-NEXT: xorl %edx, %edx 1029; X86-NEXT: .LBB33_2: 1030; X86-NEXT: popl %esi 1031; X86-NEXT: retl 1032; 1033; X64-LABEL: reg64_lshr_by_add_of_negated_amts: 1034; X64: # %bb.0: 1035; X64-NEXT: movq %rdi, %rax 1036; X64-NEXT: leal (%rdx,%rsi), %ecx 1037; X64-NEXT: negb %cl 1038; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1039; X64-NEXT: shrq %cl, %rax 1040; X64-NEXT: retq 1041 %nega = sub i64 64, %a 1042 %negb = sub i64 64, %b 1043 %negasubnegb = add i64 %nega, %negb 1044 %shifted = lshr i64 %val, %negasubnegb 1045 ret i64 %shifted 1046} 1047 1048;==============================================================================; 1049; and patterns with an actual negation+addition 1050 1051define i32 @reg32_lshr_by_negated_unfolded(i32 %val, i32 %shamt) nounwind { 1052; X86-LABEL: reg32_lshr_by_negated_unfolded: 1053; X86: # %bb.0: 1054; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1055; X86-NEXT: xorl %ecx, %ecx 1056; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 1057; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1058; X86-NEXT: shrl %cl, %eax 1059; X86-NEXT: retl 1060; 1061; X64-LABEL: reg32_lshr_by_negated_unfolded: 1062; X64: # %bb.0: 1063; X64-NEXT: movl %esi, %ecx 1064; X64-NEXT: movl %edi, %eax 1065; X64-NEXT: negb %cl 1066; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1067; X64-NEXT: shrl %cl, %eax 1068; X64-NEXT: retq 1069 %negshamt = sub i32 0, %shamt 1070 %negaaddbitwidth = add i32 %negshamt, 32 1071 %shifted = lshr i32 %val, %negaaddbitwidth 1072 ret i32 %shifted 1073} 1074define i64 @reg64_lshr_by_negated_unfolded(i64 %val, i64 %shamt) nounwind { 1075; X86-LABEL: reg64_lshr_by_negated_unfolded: 1076; X86: # %bb.0: 1077; X86-NEXT: pushl %esi 1078; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1079; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1080; X86-NEXT: movb $64, %cl 1081; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 1082; X86-NEXT: movl %esi, %edx 1083; X86-NEXT: shrl %cl, %edx 1084; X86-NEXT: shrdl %cl, %esi, %eax 1085; X86-NEXT: testb $32, %cl 1086; X86-NEXT: je .LBB35_2 1087; X86-NEXT: # %bb.1: 1088; X86-NEXT: movl %edx, %eax 1089; X86-NEXT: xorl %edx, %edx 1090; X86-NEXT: .LBB35_2: 1091; X86-NEXT: popl %esi 1092; X86-NEXT: retl 1093; 1094; X64-LABEL: reg64_lshr_by_negated_unfolded: 1095; X64: # %bb.0: 1096; X64-NEXT: movq %rsi, %rcx 1097; X64-NEXT: movq %rdi, %rax 1098; X64-NEXT: negb %cl 1099; X64-NEXT: # kill: def $cl killed $cl killed $rcx 1100; X64-NEXT: shrq %cl, %rax 1101; X64-NEXT: retq 1102 %negshamt = sub i64 0, %shamt 1103 %negaaddbitwidth = add i64 %negshamt, 64 1104 %shifted = lshr i64 %val, %negaaddbitwidth 1105 ret i64 %shifted 1106} 1107 1108define i32 @reg32_lshr_by_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind { 1109; X86-LABEL: reg32_lshr_by_negated_unfolded_sub_b: 1110; X86: # %bb.0: 1111; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1112; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1113; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 1114; X86-NEXT: negb %cl 1115; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1116; X86-NEXT: shrl %cl, %eax 1117; X86-NEXT: retl 1118; 1119; X64-LABEL: reg32_lshr_by_negated_unfolded_sub_b: 1120; X64: # %bb.0: 1121; X64-NEXT: # kill: def $edx killed $edx def $rdx 1122; X64-NEXT: # kill: def $esi killed $esi def $rsi 1123; X64-NEXT: movl %edi, %eax 1124; X64-NEXT: leal (%rsi,%rdx), %ecx 1125; X64-NEXT: negb %cl 1126; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1127; X64-NEXT: shrl %cl, %eax 1128; X64-NEXT: retq 1129 %nega = sub i32 0, %a 1130 %negaaddbitwidth = add i32 %nega, 32 1131 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b 1132 %shifted = lshr i32 %val, %negaaddbitwidthsubb 1133 ret i32 %shifted 1134} 1135define i64 @reg64_lshr_by_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind { 1136; X86-LABEL: reg64_lshr_by_negated_unfolded_sub_b: 1137; X86: # %bb.0: 1138; X86-NEXT: pushl %esi 1139; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1140; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1141; X86-NEXT: movl {{[0-9]+}}(%esp), %edx 1142; X86-NEXT: addl {{[0-9]+}}(%esp), %edx 1143; X86-NEXT: movb $64, %cl 1144; X86-NEXT: subb %dl, %cl 1145; X86-NEXT: movl %esi, %edx 1146; X86-NEXT: shrl %cl, %edx 1147; X86-NEXT: shrdl %cl, %esi, %eax 1148; X86-NEXT: testb $32, %cl 1149; X86-NEXT: je .LBB37_2 1150; X86-NEXT: # %bb.1: 1151; X86-NEXT: movl %edx, %eax 1152; X86-NEXT: xorl %edx, %edx 1153; X86-NEXT: .LBB37_2: 1154; X86-NEXT: popl %esi 1155; X86-NEXT: retl 1156; 1157; X64-LABEL: reg64_lshr_by_negated_unfolded_sub_b: 1158; X64: # %bb.0: 1159; X64-NEXT: movq %rdi, %rax 1160; X64-NEXT: leal (%rdx,%rsi), %ecx 1161; X64-NEXT: negb %cl 1162; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1163; X64-NEXT: shrq %cl, %rax 1164; X64-NEXT: retq 1165 %nega = sub i64 0, %a 1166 %negaaddbitwidth = add i64 %nega, 64 1167 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b 1168 %shifted = lshr i64 %val, %negaaddbitwidthsubb 1169 ret i64 %shifted 1170} 1171 1172define i32 @reg32_lshr_by_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind { 1173; X86-LABEL: reg32_lshr_by_b_sub_negated_unfolded: 1174; X86: # %bb.0: 1175; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1176; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1177; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 1178; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1179; X86-NEXT: shrl %cl, %eax 1180; X86-NEXT: retl 1181; 1182; X64-LABEL: reg32_lshr_by_b_sub_negated_unfolded: 1183; X64: # %bb.0: 1184; X64-NEXT: # kill: def $edx killed $edx def $rdx 1185; X64-NEXT: # kill: def $esi killed $esi def $rsi 1186; X64-NEXT: movl %edi, %eax 1187; X64-NEXT: leal (%rsi,%rdx), %ecx 1188; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1189; X64-NEXT: shrl %cl, %eax 1190; X64-NEXT: retq 1191 %nega = sub i32 0, %a 1192 %negaaddbitwidth = add i32 %nega, 32 1193 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth 1194 %shifted = lshr i32 %val, %negaaddbitwidthsubb 1195 ret i32 %shifted 1196} 1197define i64 @reg64_lshr_by_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind { 1198; X86-LABEL: reg64_lshr_by_b_sub_negated_unfolded: 1199; X86: # %bb.0: 1200; X86-NEXT: pushl %esi 1201; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1202; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1203; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1204; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 1205; X86-NEXT: addb $-64, %cl 1206; X86-NEXT: movl %esi, %edx 1207; X86-NEXT: shrl %cl, %edx 1208; X86-NEXT: shrdl %cl, %esi, %eax 1209; X86-NEXT: testb $32, %cl 1210; X86-NEXT: je .LBB39_2 1211; X86-NEXT: # %bb.1: 1212; X86-NEXT: movl %edx, %eax 1213; X86-NEXT: xorl %edx, %edx 1214; X86-NEXT: .LBB39_2: 1215; X86-NEXT: popl %esi 1216; X86-NEXT: retl 1217; 1218; X64-LABEL: reg64_lshr_by_b_sub_negated_unfolded: 1219; X64: # %bb.0: 1220; X64-NEXT: movq %rdi, %rax 1221; X64-NEXT: leal (%rdx,%rsi), %ecx 1222; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1223; X64-NEXT: shrq %cl, %rax 1224; X64-NEXT: retq 1225 %nega = sub i64 0, %a 1226 %negaaddbitwidth = add i64 %nega, 64 1227 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth 1228 %shifted = lshr i64 %val, %negaaddbitwidthsubb 1229 ret i64 %shifted 1230} 1231 1232define i32 @reg32_lshr_by_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind { 1233; X86-LABEL: reg32_lshr_by_negated_unfolded_add_b: 1234; X86: # %bb.0: 1235; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1236; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1237; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1238; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1239; X86-NEXT: shrl %cl, %eax 1240; X86-NEXT: retl 1241; 1242; X64-LABEL: reg32_lshr_by_negated_unfolded_add_b: 1243; X64: # %bb.0: 1244; X64-NEXT: movl %edx, %ecx 1245; X64-NEXT: movl %edi, %eax 1246; X64-NEXT: subl %esi, %ecx 1247; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1248; X64-NEXT: shrl %cl, %eax 1249; X64-NEXT: retq 1250 %nega = sub i32 0, %a 1251 %negaaddbitwidth = add i32 %nega, 32 1252 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b 1253 %shifted = lshr i32 %val, %negaaddbitwidthaddb 1254 ret i32 %shifted 1255} 1256define i64 @reg64_lshr_by_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind { 1257; X86-LABEL: reg64_lshr_by_negated_unfolded_add_b: 1258; X86: # %bb.0: 1259; X86-NEXT: pushl %esi 1260; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1261; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1262; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1263; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1264; X86-NEXT: addb $64, %cl 1265; X86-NEXT: movl %esi, %edx 1266; X86-NEXT: shrl %cl, %edx 1267; X86-NEXT: shrdl %cl, %esi, %eax 1268; X86-NEXT: testb $32, %cl 1269; X86-NEXT: je .LBB41_2 1270; X86-NEXT: # %bb.1: 1271; X86-NEXT: movl %edx, %eax 1272; X86-NEXT: xorl %edx, %edx 1273; X86-NEXT: .LBB41_2: 1274; X86-NEXT: popl %esi 1275; X86-NEXT: retl 1276; 1277; X64-LABEL: reg64_lshr_by_negated_unfolded_add_b: 1278; X64: # %bb.0: 1279; X64-NEXT: movq %rdx, %rcx 1280; X64-NEXT: movq %rdi, %rax 1281; X64-NEXT: subl %esi, %ecx 1282; X64-NEXT: # kill: def $cl killed $cl killed $rcx 1283; X64-NEXT: shrq %cl, %rax 1284; X64-NEXT: retq 1285 %nega = sub i64 0, %a 1286 %negaaddbitwidth = add i64 %nega, 64 1287 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b 1288 %shifted = lshr i64 %val, %negaaddbitwidthaddb 1289 ret i64 %shifted 1290} 1291 1292;==============================================================================; 1293; and patterns with an actual negation+mask 1294 1295define i32 @reg32_lshr_by_masked_negated_unfolded(i32 %val, i32 %shamt) nounwind { 1296; X86-LABEL: reg32_lshr_by_masked_negated_unfolded: 1297; X86: # %bb.0: 1298; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1299; X86-NEXT: xorl %ecx, %ecx 1300; X86-NEXT: subb {{[0-9]+}}(%esp), %cl 1301; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1302; X86-NEXT: shrl %cl, %eax 1303; X86-NEXT: retl 1304; 1305; X64-LABEL: reg32_lshr_by_masked_negated_unfolded: 1306; X64: # %bb.0: 1307; X64-NEXT: movl %esi, %ecx 1308; X64-NEXT: movl %edi, %eax 1309; X64-NEXT: negb %cl 1310; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1311; X64-NEXT: shrl %cl, %eax 1312; X64-NEXT: retq 1313 %negshamt = sub i32 0, %shamt 1314 %negaaddbitwidth = and i32 %negshamt, 31 1315 %shifted = lshr i32 %val, %negaaddbitwidth 1316 ret i32 %shifted 1317} 1318define i64 @reg64_lshr_by_masked_negated_unfolded(i64 %val, i64 %shamt) nounwind { 1319; X86-LABEL: reg64_lshr_by_masked_negated_unfolded: 1320; X86: # %bb.0: 1321; X86-NEXT: pushl %esi 1322; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1323; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1324; X86-NEXT: xorl %ecx, %ecx 1325; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx 1326; X86-NEXT: subb %dl, %cl 1327; X86-NEXT: movl %esi, %edx 1328; X86-NEXT: shrl %cl, %edx 1329; X86-NEXT: shrdl %cl, %esi, %eax 1330; X86-NEXT: testb $32, %cl 1331; X86-NEXT: je .LBB43_2 1332; X86-NEXT: # %bb.1: 1333; X86-NEXT: movl %edx, %eax 1334; X86-NEXT: xorl %edx, %edx 1335; X86-NEXT: .LBB43_2: 1336; X86-NEXT: popl %esi 1337; X86-NEXT: retl 1338; 1339; X64-LABEL: reg64_lshr_by_masked_negated_unfolded: 1340; X64: # %bb.0: 1341; X64-NEXT: movq %rsi, %rcx 1342; X64-NEXT: movq %rdi, %rax 1343; X64-NEXT: negb %cl 1344; X64-NEXT: # kill: def $cl killed $cl killed $rcx 1345; X64-NEXT: shrq %cl, %rax 1346; X64-NEXT: retq 1347 %negshamt = sub i64 0, %shamt 1348 %negaaddbitwidth = and i64 %negshamt, 63 1349 %shifted = lshr i64 %val, %negaaddbitwidth 1350 ret i64 %shifted 1351} 1352 1353define i32 @reg32_lshr_by_masked_negated_unfolded_sub_b(i32 %val, i32 %a, i32 %b) nounwind { 1354; X86-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b: 1355; X86: # %bb.0: 1356; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1357; X86-NEXT: xorl %ecx, %ecx 1358; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1359; X86-NEXT: andl $31, %ecx 1360; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1361; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1362; X86-NEXT: shrl %cl, %eax 1363; X86-NEXT: retl 1364; 1365; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b: 1366; X64: # %bb.0: 1367; X64-NEXT: movl %esi, %ecx 1368; X64-NEXT: movl %edi, %eax 1369; X64-NEXT: negl %ecx 1370; X64-NEXT: andl $31, %ecx 1371; X64-NEXT: subl %edx, %ecx 1372; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1373; X64-NEXT: shrl %cl, %eax 1374; X64-NEXT: retq 1375 %nega = sub i32 0, %a 1376 %negaaddbitwidth = and i32 %nega, 31 1377 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b 1378 %shifted = lshr i32 %val, %negaaddbitwidthsubb 1379 ret i32 %shifted 1380} 1381define i64 @reg64_lshr_by_masked_negated_unfolded_sub_b(i64 %val, i64 %a, i64 %b) nounwind { 1382; X86-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b: 1383; X86: # %bb.0: 1384; X86-NEXT: pushl %esi 1385; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1386; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1387; X86-NEXT: xorl %ecx, %ecx 1388; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1389; X86-NEXT: andl $63, %ecx 1390; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1391; X86-NEXT: movl %esi, %edx 1392; X86-NEXT: shrl %cl, %edx 1393; X86-NEXT: shrdl %cl, %esi, %eax 1394; X86-NEXT: testb $32, %cl 1395; X86-NEXT: je .LBB45_2 1396; X86-NEXT: # %bb.1: 1397; X86-NEXT: movl %edx, %eax 1398; X86-NEXT: xorl %edx, %edx 1399; X86-NEXT: .LBB45_2: 1400; X86-NEXT: popl %esi 1401; X86-NEXT: retl 1402; 1403; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b: 1404; X64: # %bb.0: 1405; X64-NEXT: movq %rsi, %rcx 1406; X64-NEXT: movq %rdi, %rax 1407; X64-NEXT: negl %ecx 1408; X64-NEXT: andl $63, %ecx 1409; X64-NEXT: subl %edx, %ecx 1410; X64-NEXT: # kill: def $cl killed $cl killed $rcx 1411; X64-NEXT: shrq %cl, %rax 1412; X64-NEXT: retq 1413 %nega = sub i64 0, %a 1414 %negaaddbitwidth = and i64 %nega, 63 1415 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b 1416 %shifted = lshr i64 %val, %negaaddbitwidthsubb 1417 ret i64 %shifted 1418} 1419 1420define i32 @reg32_lshr_by_masked_b_sub_negated_unfolded(i32 %val, i32 %a, i32 %b) nounwind { 1421; X86-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded: 1422; X86: # %bb.0: 1423; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1424; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1425; X86-NEXT: xorl %edx, %edx 1426; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 1427; X86-NEXT: andl $31, %edx 1428; X86-NEXT: subl %edx, %ecx 1429; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1430; X86-NEXT: shrl %cl, %eax 1431; X86-NEXT: retl 1432; 1433; X64-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded: 1434; X64: # %bb.0: 1435; X64-NEXT: movl %edx, %ecx 1436; X64-NEXT: movl %edi, %eax 1437; X64-NEXT: negl %esi 1438; X64-NEXT: andl $31, %esi 1439; X64-NEXT: subl %esi, %ecx 1440; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1441; X64-NEXT: shrl %cl, %eax 1442; X64-NEXT: retq 1443 %nega = sub i32 0, %a 1444 %negaaddbitwidth = and i32 %nega, 31 1445 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth 1446 %shifted = lshr i32 %val, %negaaddbitwidthsubb 1447 ret i32 %shifted 1448} 1449define i64 @reg64_lshr_by_masked_b_sub_negated_unfolded(i64 %val, i64 %a, i64 %b) nounwind { 1450; X86-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded: 1451; X86: # %bb.0: 1452; X86-NEXT: pushl %esi 1453; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1454; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1455; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 1456; X86-NEXT: xorl %edx, %edx 1457; X86-NEXT: subl {{[0-9]+}}(%esp), %edx 1458; X86-NEXT: andl $63, %edx 1459; X86-NEXT: subl %edx, %ecx 1460; X86-NEXT: movl %esi, %edx 1461; X86-NEXT: shrl %cl, %edx 1462; X86-NEXT: shrdl %cl, %esi, %eax 1463; X86-NEXT: testb $32, %cl 1464; X86-NEXT: je .LBB47_2 1465; X86-NEXT: # %bb.1: 1466; X86-NEXT: movl %edx, %eax 1467; X86-NEXT: xorl %edx, %edx 1468; X86-NEXT: .LBB47_2: 1469; X86-NEXT: popl %esi 1470; X86-NEXT: retl 1471; 1472; X64-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded: 1473; X64: # %bb.0: 1474; X64-NEXT: movq %rdx, %rcx 1475; X64-NEXT: movq %rdi, %rax 1476; X64-NEXT: negl %esi 1477; X64-NEXT: andl $63, %esi 1478; X64-NEXT: subl %esi, %ecx 1479; X64-NEXT: # kill: def $cl killed $cl killed $rcx 1480; X64-NEXT: shrq %cl, %rax 1481; X64-NEXT: retq 1482 %nega = sub i64 0, %a 1483 %negaaddbitwidth = and i64 %nega, 63 1484 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth 1485 %shifted = lshr i64 %val, %negaaddbitwidthsubb 1486 ret i64 %shifted 1487} 1488 1489define i32 @reg32_lshr_by_masked_negated_unfolded_add_b(i32 %val, i32 %a, i32 %b) nounwind { 1490; X86-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b: 1491; X86: # %bb.0: 1492; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1493; X86-NEXT: xorl %ecx, %ecx 1494; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1495; X86-NEXT: andl $31, %ecx 1496; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 1497; X86-NEXT: # kill: def $cl killed $cl killed $ecx 1498; X86-NEXT: shrl %cl, %eax 1499; X86-NEXT: retl 1500; 1501; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b: 1502; X64: # %bb.0: 1503; X64-NEXT: # kill: def $edx killed $edx def $rdx 1504; X64-NEXT: # kill: def $esi killed $esi def $rsi 1505; X64-NEXT: movl %edi, %eax 1506; X64-NEXT: negl %esi 1507; X64-NEXT: andl $31, %esi 1508; X64-NEXT: leal (%rsi,%rdx), %ecx 1509; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1510; X64-NEXT: shrl %cl, %eax 1511; X64-NEXT: retq 1512 %nega = sub i32 0, %a 1513 %negaaddbitwidth = and i32 %nega, 31 1514 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b 1515 %shifted = lshr i32 %val, %negaaddbitwidthaddb 1516 ret i32 %shifted 1517} 1518define i64 @reg64_lshr_by_masked_negated_unfolded_add_b(i64 %val, i64 %a, i64 %b) nounwind { 1519; X86-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b: 1520; X86: # %bb.0: 1521; X86-NEXT: pushl %esi 1522; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1523; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 1524; X86-NEXT: xorl %ecx, %ecx 1525; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx 1526; X86-NEXT: andl $63, %ecx 1527; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx 1528; X86-NEXT: movl %esi, %edx 1529; X86-NEXT: shrl %cl, %edx 1530; X86-NEXT: shrdl %cl, %esi, %eax 1531; X86-NEXT: testb $32, %cl 1532; X86-NEXT: je .LBB49_2 1533; X86-NEXT: # %bb.1: 1534; X86-NEXT: movl %edx, %eax 1535; X86-NEXT: xorl %edx, %edx 1536; X86-NEXT: .LBB49_2: 1537; X86-NEXT: popl %esi 1538; X86-NEXT: retl 1539; 1540; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b: 1541; X64: # %bb.0: 1542; X64-NEXT: movq %rdi, %rax 1543; X64-NEXT: negl %esi 1544; X64-NEXT: andl $63, %esi 1545; X64-NEXT: leal (%rdx,%rsi), %ecx 1546; X64-NEXT: # kill: def $cl killed $cl killed $ecx 1547; X64-NEXT: shrq %cl, %rax 1548; X64-NEXT: retq 1549 %nega = sub i64 0, %a 1550 %negaaddbitwidth = and i64 %nega, 63 1551 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b 1552 %shifted = lshr i64 %val, %negaaddbitwidthaddb 1553 ret i64 %shifted 1554} 1555 1556define i16 @sh_trunc_sh(i64 %x) { 1557; X86-LABEL: sh_trunc_sh: 1558; X86: # %bb.0: 1559; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 1560; X86-NEXT: shrl $4, %eax 1561; X86-NEXT: andl $15, %eax 1562; X86-NEXT: # kill: def $ax killed $ax killed $eax 1563; X86-NEXT: retl 1564; 1565; X64-LABEL: sh_trunc_sh: 1566; X64: # %bb.0: 1567; X64-NEXT: movq %rdi, %rax 1568; X64-NEXT: shrq $36, %rax 1569; X64-NEXT: andl $15, %eax 1570; X64-NEXT: # kill: def $ax killed $ax killed $rax 1571; X64-NEXT: retq 1572 %s = lshr i64 %x, 24 1573 %t = trunc i64 %s to i16 1574 %r = lshr i16 %t, 12 1575 ret i16 %r 1576} 1577