1577 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefix=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefix=X644 5;==============================================================================;6; the shift amount is negated (shiftbitwidth - shiftamt)7;==============================================================================;8 9; shift left10;------------------------------------------------------------------------------;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), %eax16; X86-NEXT: xorl %ecx, %ecx17; X86-NEXT: subb {{[0-9]+}}(%esp), %cl18; X86-NEXT: # kill: def $cl killed $cl killed $ecx19; X86-NEXT: shll %cl, %eax20; X86-NEXT: retl21;22; X64-LABEL: reg32_shl_by_negated:23; X64: # %bb.0:24; X64-NEXT: movl %esi, %ecx25; X64-NEXT: movl %edi, %eax26; X64-NEXT: negb %cl27; X64-NEXT: # kill: def $cl killed $cl killed $ecx28; X64-NEXT: shll %cl, %eax29; X64-NEXT: retq30 %negshamt = sub i32 32, %shamt31 %shifted = shl i32 %val, %negshamt32 ret i32 %shifted33}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), %eax38; X86-NEXT: movl (%eax), %eax39; X86-NEXT: xorl %ecx, %ecx40; X86-NEXT: subb {{[0-9]+}}(%esp), %cl41; X86-NEXT: # kill: def $cl killed $cl killed $ecx42; X86-NEXT: shll %cl, %eax43; X86-NEXT: retl44;45; X64-LABEL: load32_shl_by_negated:46; X64: # %bb.0:47; X64-NEXT: movl %esi, %ecx48; X64-NEXT: movl (%rdi), %eax49; X64-NEXT: negb %cl50; X64-NEXT: # kill: def $cl killed $cl killed $ecx51; X64-NEXT: shll %cl, %eax52; X64-NEXT: retq53 %val = load i32, ptr %valptr54 %negshamt = sub i32 32, %shamt55 %shifted = shl i32 %val, %negshamt56 ret i32 %shifted57}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), %eax62; X86-NEXT: movl {{[0-9]+}}(%esp), %edx63; X86-NEXT: xorl %ecx, %ecx64; X86-NEXT: subb {{[0-9]+}}(%esp), %cl65; X86-NEXT: # kill: def $cl killed $cl killed $ecx66; X86-NEXT: shll %cl, %edx67; X86-NEXT: movl %edx, (%eax)68; X86-NEXT: retl69;70; X64-LABEL: store32_shl_by_negated:71; X64: # %bb.0:72; X64-NEXT: movl %edx, %ecx73; X64-NEXT: negb %cl74; X64-NEXT: # kill: def $cl killed $cl killed $ecx75; X64-NEXT: shll %cl, %edi76; X64-NEXT: movl %edi, (%rsi)77; X64-NEXT: retq78 %negshamt = sub i32 32, %shamt79 %shifted = shl i32 %val, %negshamt80 store i32 %shifted, ptr %dstptr81 ret void82}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), %eax87; X86-NEXT: movb $32, %cl88; X86-NEXT: subb {{[0-9]+}}(%esp), %cl89; X86-NEXT: shll %cl, (%eax)90; X86-NEXT: retl91;92; X64-LABEL: modify32_shl_by_negated:93; X64: # %bb.0:94; X64-NEXT: movb $32, %cl95; X64-NEXT: subb %sil, %cl96; X64-NEXT: shll %cl, (%rdi)97; X64-NEXT: retq98 %val = load i32, ptr %valptr99 %negshamt = sub i32 32, %shamt100 %shifted = shl i32 %val, %negshamt101 store i32 %shifted, ptr %valptr102 ret void103}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 %esi109; X86-NEXT: movl {{[0-9]+}}(%esp), %esi110; X86-NEXT: movl {{[0-9]+}}(%esp), %edx111; X86-NEXT: movb $64, %cl112; X86-NEXT: subb {{[0-9]+}}(%esp), %cl113; X86-NEXT: movl %esi, %eax114; X86-NEXT: shll %cl, %eax115; X86-NEXT: shldl %cl, %esi, %edx116; X86-NEXT: testb $32, %cl117; X86-NEXT: je .LBB4_2118; X86-NEXT: # %bb.1:119; X86-NEXT: movl %eax, %edx120; X86-NEXT: xorl %eax, %eax121; X86-NEXT: .LBB4_2:122; X86-NEXT: popl %esi123; X86-NEXT: retl124;125; X64-LABEL: reg64_shl_by_negated:126; X64: # %bb.0:127; X64-NEXT: movq %rsi, %rcx128; X64-NEXT: movq %rdi, %rax129; X64-NEXT: negb %cl130; X64-NEXT: # kill: def $cl killed $cl killed $rcx131; X64-NEXT: shlq %cl, %rax132; X64-NEXT: retq133 %negshamt = sub i64 64, %shamt134 %shifted = shl i64 %val, %negshamt135 ret i64 %shifted136}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 %esi141; X86-NEXT: movl {{[0-9]+}}(%esp), %eax142; X86-NEXT: movl (%eax), %esi143; X86-NEXT: movl 4(%eax), %edx144; X86-NEXT: movb $64, %cl145; X86-NEXT: subb {{[0-9]+}}(%esp), %cl146; X86-NEXT: movl %esi, %eax147; X86-NEXT: shll %cl, %eax148; X86-NEXT: shldl %cl, %esi, %edx149; X86-NEXT: testb $32, %cl150; X86-NEXT: je .LBB5_2151; X86-NEXT: # %bb.1:152; X86-NEXT: movl %eax, %edx153; X86-NEXT: xorl %eax, %eax154; X86-NEXT: .LBB5_2:155; X86-NEXT: popl %esi156; X86-NEXT: retl157;158; X64-LABEL: load64_shl_by_negated:159; X64: # %bb.0:160; X64-NEXT: movq %rsi, %rcx161; X64-NEXT: movq (%rdi), %rax162; X64-NEXT: negb %cl163; X64-NEXT: # kill: def $cl killed $cl killed $rcx164; X64-NEXT: shlq %cl, %rax165; X64-NEXT: retq166 %val = load i64, ptr %valptr167 %negshamt = sub i64 64, %shamt168 %shifted = shl i64 %val, %negshamt169 ret i64 %shifted170}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 %edi175; X86-NEXT: pushl %esi176; X86-NEXT: movl {{[0-9]+}}(%esp), %eax177; X86-NEXT: movl {{[0-9]+}}(%esp), %edi178; X86-NEXT: movl {{[0-9]+}}(%esp), %edx179; X86-NEXT: movb $64, %cl180; X86-NEXT: subb {{[0-9]+}}(%esp), %cl181; X86-NEXT: movl %edi, %esi182; X86-NEXT: shll %cl, %esi183; X86-NEXT: shldl %cl, %edi, %edx184; X86-NEXT: testb $32, %cl185; X86-NEXT: je .LBB6_2186; X86-NEXT: # %bb.1:187; X86-NEXT: movl %esi, %edx188; X86-NEXT: xorl %esi, %esi189; X86-NEXT: .LBB6_2:190; X86-NEXT: movl %edx, 4(%eax)191; X86-NEXT: movl %esi, (%eax)192; X86-NEXT: popl %esi193; X86-NEXT: popl %edi194; X86-NEXT: retl195;196; X64-LABEL: store64_shl_by_negated:197; X64: # %bb.0:198; X64-NEXT: movq %rdx, %rcx199; X64-NEXT: negb %cl200; X64-NEXT: # kill: def $cl killed $cl killed $rcx201; X64-NEXT: shlq %cl, %rdi202; X64-NEXT: movq %rdi, (%rsi)203; X64-NEXT: retq204 %negshamt = sub i64 64, %shamt205 %shifted = shl i64 %val, %negshamt206 store i64 %shifted, ptr %dstptr207 ret void208}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 %edi213; X86-NEXT: pushl %esi214; X86-NEXT: movl {{[0-9]+}}(%esp), %eax215; X86-NEXT: movl (%eax), %edi216; X86-NEXT: movl 4(%eax), %edx217; X86-NEXT: movb $64, %cl218; X86-NEXT: subb {{[0-9]+}}(%esp), %cl219; X86-NEXT: movl %edi, %esi220; X86-NEXT: shll %cl, %esi221; X86-NEXT: shldl %cl, %edi, %edx222; X86-NEXT: testb $32, %cl223; X86-NEXT: je .LBB7_2224; X86-NEXT: # %bb.1:225; X86-NEXT: movl %esi, %edx226; X86-NEXT: xorl %esi, %esi227; X86-NEXT: .LBB7_2:228; X86-NEXT: movl %esi, (%eax)229; X86-NEXT: movl %edx, 4(%eax)230; X86-NEXT: popl %esi231; X86-NEXT: popl %edi232; X86-NEXT: retl233;234; X64-LABEL: modify64_shl_by_negated:235; X64: # %bb.0:236; X64-NEXT: movb $64, %cl237; X64-NEXT: subb %sil, %cl238; X64-NEXT: shlq %cl, (%rdi)239; X64-NEXT: retq240 %val = load i64, ptr %valptr241 %negshamt = sub i64 64, %shamt242 %shifted = shl i64 %val, %negshamt243 store i64 %shifted, ptr %valptr244 ret void245}246 247; logical shift right248;------------------------------------------------------------------------------;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), %eax254; X86-NEXT: xorl %ecx, %ecx255; X86-NEXT: subb {{[0-9]+}}(%esp), %cl256; X86-NEXT: # kill: def $cl killed $cl killed $ecx257; X86-NEXT: shrl %cl, %eax258; X86-NEXT: retl259;260; X64-LABEL: reg32_lshr_by_negated:261; X64: # %bb.0:262; X64-NEXT: movl %esi, %ecx263; X64-NEXT: movl %edi, %eax264; X64-NEXT: negb %cl265; X64-NEXT: # kill: def $cl killed $cl killed $ecx266; X64-NEXT: shrl %cl, %eax267; X64-NEXT: retq268 %negshamt = sub i32 32, %shamt269 %shifted = lshr i32 %val, %negshamt270 ret i32 %shifted271}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), %eax276; X86-NEXT: movl (%eax), %eax277; X86-NEXT: xorl %ecx, %ecx278; X86-NEXT: subb {{[0-9]+}}(%esp), %cl279; X86-NEXT: # kill: def $cl killed $cl killed $ecx280; X86-NEXT: shrl %cl, %eax281; X86-NEXT: retl282;283; X64-LABEL: load32_lshr_by_negated:284; X64: # %bb.0:285; X64-NEXT: movl %esi, %ecx286; X64-NEXT: movl (%rdi), %eax287; X64-NEXT: negb %cl288; X64-NEXT: # kill: def $cl killed $cl killed $ecx289; X64-NEXT: shrl %cl, %eax290; X64-NEXT: retq291 %val = load i32, ptr %valptr292 %negshamt = sub i32 32, %shamt293 %shifted = lshr i32 %val, %negshamt294 ret i32 %shifted295}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), %eax300; X86-NEXT: movl {{[0-9]+}}(%esp), %edx301; X86-NEXT: xorl %ecx, %ecx302; X86-NEXT: subb {{[0-9]+}}(%esp), %cl303; X86-NEXT: # kill: def $cl killed $cl killed $ecx304; X86-NEXT: shrl %cl, %edx305; X86-NEXT: movl %edx, (%eax)306; X86-NEXT: retl307;308; X64-LABEL: store32_lshr_by_negated:309; X64: # %bb.0:310; X64-NEXT: movl %edx, %ecx311; X64-NEXT: negb %cl312; X64-NEXT: # kill: def $cl killed $cl killed $ecx313; X64-NEXT: shrl %cl, %edi314; X64-NEXT: movl %edi, (%rsi)315; X64-NEXT: retq316 %negshamt = sub i32 32, %shamt317 %shifted = lshr i32 %val, %negshamt318 store i32 %shifted, ptr %dstptr319 ret void320}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), %eax325; X86-NEXT: movb $32, %cl326; X86-NEXT: subb {{[0-9]+}}(%esp), %cl327; X86-NEXT: shrl %cl, (%eax)328; X86-NEXT: retl329;330; X64-LABEL: modify32_lshr_by_negated:331; X64: # %bb.0:332; X64-NEXT: movb $32, %cl333; X64-NEXT: subb %sil, %cl334; X64-NEXT: shrl %cl, (%rdi)335; X64-NEXT: retq336 %val = load i32, ptr %valptr337 %negshamt = sub i32 32, %shamt338 %shifted = lshr i32 %val, %negshamt339 store i32 %shifted, ptr %valptr340 ret void341}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 %esi347; X86-NEXT: movl {{[0-9]+}}(%esp), %eax348; X86-NEXT: movl {{[0-9]+}}(%esp), %esi349; X86-NEXT: movb $64, %cl350; X86-NEXT: subb {{[0-9]+}}(%esp), %cl351; X86-NEXT: movl %esi, %edx352; X86-NEXT: shrl %cl, %edx353; X86-NEXT: shrdl %cl, %esi, %eax354; X86-NEXT: testb $32, %cl355; X86-NEXT: je .LBB12_2356; X86-NEXT: # %bb.1:357; X86-NEXT: movl %edx, %eax358; X86-NEXT: xorl %edx, %edx359; X86-NEXT: .LBB12_2:360; X86-NEXT: popl %esi361; X86-NEXT: retl362;363; X64-LABEL: reg64_lshr_by_negated:364; X64: # %bb.0:365; X64-NEXT: movq %rsi, %rcx366; X64-NEXT: movq %rdi, %rax367; X64-NEXT: negb %cl368; X64-NEXT: # kill: def $cl killed $cl killed $rcx369; X64-NEXT: shrq %cl, %rax370; X64-NEXT: retq371 %negshamt = sub i64 64, %shamt372 %shifted = lshr i64 %val, %negshamt373 ret i64 %shifted374}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 %esi379; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx380; X86-NEXT: movl (%ecx), %eax381; X86-NEXT: movl 4(%ecx), %esi382; X86-NEXT: movb $64, %cl383; X86-NEXT: subb {{[0-9]+}}(%esp), %cl384; X86-NEXT: movl %esi, %edx385; X86-NEXT: shrl %cl, %edx386; X86-NEXT: shrdl %cl, %esi, %eax387; X86-NEXT: testb $32, %cl388; X86-NEXT: je .LBB13_2389; X86-NEXT: # %bb.1:390; X86-NEXT: movl %edx, %eax391; X86-NEXT: xorl %edx, %edx392; X86-NEXT: .LBB13_2:393; X86-NEXT: popl %esi394; X86-NEXT: retl395;396; X64-LABEL: load64_lshr_by_negated:397; X64: # %bb.0:398; X64-NEXT: movq %rsi, %rcx399; X64-NEXT: movq (%rdi), %rax400; X64-NEXT: negb %cl401; X64-NEXT: # kill: def $cl killed $cl killed $rcx402; X64-NEXT: shrq %cl, %rax403; X64-NEXT: retq404 %val = load i64, ptr %valptr405 %negshamt = sub i64 64, %shamt406 %shifted = lshr i64 %val, %negshamt407 ret i64 %shifted408}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 %edi413; X86-NEXT: pushl %esi414; X86-NEXT: movl {{[0-9]+}}(%esp), %eax415; X86-NEXT: movl {{[0-9]+}}(%esp), %edx416; X86-NEXT: movl {{[0-9]+}}(%esp), %edi417; X86-NEXT: movb $64, %cl418; X86-NEXT: subb {{[0-9]+}}(%esp), %cl419; X86-NEXT: movl %edi, %esi420; X86-NEXT: shrl %cl, %esi421; X86-NEXT: shrdl %cl, %edi, %edx422; X86-NEXT: testb $32, %cl423; X86-NEXT: je .LBB14_2424; X86-NEXT: # %bb.1:425; X86-NEXT: movl %esi, %edx426; X86-NEXT: xorl %esi, %esi427; X86-NEXT: .LBB14_2:428; X86-NEXT: movl %esi, 4(%eax)429; X86-NEXT: movl %edx, (%eax)430; X86-NEXT: popl %esi431; X86-NEXT: popl %edi432; X86-NEXT: retl433;434; X64-LABEL: store64_lshr_by_negated:435; X64: # %bb.0:436; X64-NEXT: movq %rdx, %rcx437; X64-NEXT: negb %cl438; X64-NEXT: # kill: def $cl killed $cl killed $rcx439; X64-NEXT: shrq %cl, %rdi440; X64-NEXT: movq %rdi, (%rsi)441; X64-NEXT: retq442 %negshamt = sub i64 64, %shamt443 %shifted = lshr i64 %val, %negshamt444 store i64 %shifted, ptr %dstptr445 ret void446}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 %edi451; X86-NEXT: pushl %esi452; X86-NEXT: movl {{[0-9]+}}(%esp), %eax453; X86-NEXT: movl (%eax), %edx454; X86-NEXT: movl 4(%eax), %edi455; X86-NEXT: movb $64, %cl456; X86-NEXT: subb {{[0-9]+}}(%esp), %cl457; X86-NEXT: movl %edi, %esi458; X86-NEXT: shrl %cl, %esi459; X86-NEXT: shrdl %cl, %edi, %edx460; X86-NEXT: testb $32, %cl461; X86-NEXT: je .LBB15_2462; X86-NEXT: # %bb.1:463; X86-NEXT: movl %esi, %edx464; X86-NEXT: xorl %esi, %esi465; X86-NEXT: .LBB15_2:466; X86-NEXT: movl %edx, (%eax)467; X86-NEXT: movl %esi, 4(%eax)468; X86-NEXT: popl %esi469; X86-NEXT: popl %edi470; X86-NEXT: retl471;472; X64-LABEL: modify64_lshr_by_negated:473; X64: # %bb.0:474; X64-NEXT: movb $64, %cl475; X64-NEXT: subb %sil, %cl476; X64-NEXT: shrq %cl, (%rdi)477; X64-NEXT: retq478 %val = load i64, ptr %valptr479 %negshamt = sub i64 64, %shamt480 %shifted = lshr i64 %val, %negshamt481 store i64 %shifted, ptr %valptr482 ret void483}484 485; arithmetic shift right486;------------------------------------------------------------------------------;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), %eax492; X86-NEXT: xorl %ecx, %ecx493; X86-NEXT: subb {{[0-9]+}}(%esp), %cl494; X86-NEXT: # kill: def $cl killed $cl killed $ecx495; X86-NEXT: sarl %cl, %eax496; X86-NEXT: retl497;498; X64-LABEL: reg32_ashr_by_negated:499; X64: # %bb.0:500; X64-NEXT: movl %esi, %ecx501; X64-NEXT: movl %edi, %eax502; X64-NEXT: negb %cl503; X64-NEXT: # kill: def $cl killed $cl killed $ecx504; X64-NEXT: sarl %cl, %eax505; X64-NEXT: retq506 %negshamt = sub i32 32, %shamt507 %shifted = ashr i32 %val, %negshamt508 ret i32 %shifted509}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), %eax514; X86-NEXT: movl (%eax), %eax515; X86-NEXT: xorl %ecx, %ecx516; X86-NEXT: subb {{[0-9]+}}(%esp), %cl517; X86-NEXT: # kill: def $cl killed $cl killed $ecx518; X86-NEXT: sarl %cl, %eax519; X86-NEXT: retl520;521; X64-LABEL: load32_ashr_by_negated:522; X64: # %bb.0:523; X64-NEXT: movl %esi, %ecx524; X64-NEXT: movl (%rdi), %eax525; X64-NEXT: negb %cl526; X64-NEXT: # kill: def $cl killed $cl killed $ecx527; X64-NEXT: sarl %cl, %eax528; X64-NEXT: retq529 %val = load i32, ptr %valptr530 %negshamt = sub i32 32, %shamt531 %shifted = ashr i32 %val, %negshamt532 ret i32 %shifted533}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), %eax538; X86-NEXT: movl {{[0-9]+}}(%esp), %edx539; X86-NEXT: xorl %ecx, %ecx540; X86-NEXT: subb {{[0-9]+}}(%esp), %cl541; X86-NEXT: # kill: def $cl killed $cl killed $ecx542; X86-NEXT: sarl %cl, %edx543; X86-NEXT: movl %edx, (%eax)544; X86-NEXT: retl545;546; X64-LABEL: store32_ashr_by_negated:547; X64: # %bb.0:548; X64-NEXT: movl %edx, %ecx549; X64-NEXT: negb %cl550; X64-NEXT: # kill: def $cl killed $cl killed $ecx551; X64-NEXT: sarl %cl, %edi552; X64-NEXT: movl %edi, (%rsi)553; X64-NEXT: retq554 %negshamt = sub i32 32, %shamt555 %shifted = ashr i32 %val, %negshamt556 store i32 %shifted, ptr %dstptr557 ret void558}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), %eax563; X86-NEXT: movb $32, %cl564; X86-NEXT: subb {{[0-9]+}}(%esp), %cl565; X86-NEXT: sarl %cl, (%eax)566; X86-NEXT: retl567;568; X64-LABEL: modify32_ashr_by_negated:569; X64: # %bb.0:570; X64-NEXT: movb $32, %cl571; X64-NEXT: subb %sil, %cl572; X64-NEXT: sarl %cl, (%rdi)573; X64-NEXT: retq574 %val = load i32, ptr %valptr575 %negshamt = sub i32 32, %shamt576 %shifted = ashr i32 %val, %negshamt577 store i32 %shifted, ptr %valptr578 ret void579}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 %esi585; X86-NEXT: movl {{[0-9]+}}(%esp), %eax586; X86-NEXT: movl {{[0-9]+}}(%esp), %esi587; X86-NEXT: movb $64, %cl588; X86-NEXT: subb {{[0-9]+}}(%esp), %cl589; X86-NEXT: movl %esi, %edx590; X86-NEXT: sarl %cl, %edx591; X86-NEXT: shrdl %cl, %esi, %eax592; X86-NEXT: testb $32, %cl593; X86-NEXT: je .LBB20_2594; X86-NEXT: # %bb.1:595; X86-NEXT: sarl $31, %esi596; X86-NEXT: movl %edx, %eax597; X86-NEXT: movl %esi, %edx598; X86-NEXT: .LBB20_2:599; X86-NEXT: popl %esi600; X86-NEXT: retl601;602; X64-LABEL: reg64_ashr_by_negated:603; X64: # %bb.0:604; X64-NEXT: movq %rsi, %rcx605; X64-NEXT: movq %rdi, %rax606; X64-NEXT: negb %cl607; X64-NEXT: # kill: def $cl killed $cl killed $rcx608; X64-NEXT: sarq %cl, %rax609; X64-NEXT: retq610 %negshamt = sub i64 64, %shamt611 %shifted = ashr i64 %val, %negshamt612 ret i64 %shifted613}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 %esi618; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx619; X86-NEXT: movl (%ecx), %eax620; X86-NEXT: movl 4(%ecx), %esi621; X86-NEXT: movb $64, %cl622; X86-NEXT: subb {{[0-9]+}}(%esp), %cl623; X86-NEXT: movl %esi, %edx624; X86-NEXT: sarl %cl, %edx625; X86-NEXT: shrdl %cl, %esi, %eax626; X86-NEXT: testb $32, %cl627; X86-NEXT: je .LBB21_2628; X86-NEXT: # %bb.1:629; X86-NEXT: sarl $31, %esi630; X86-NEXT: movl %edx, %eax631; X86-NEXT: movl %esi, %edx632; X86-NEXT: .LBB21_2:633; X86-NEXT: popl %esi634; X86-NEXT: retl635;636; X64-LABEL: load64_ashr_by_negated:637; X64: # %bb.0:638; X64-NEXT: movq %rsi, %rcx639; X64-NEXT: movq (%rdi), %rax640; X64-NEXT: negb %cl641; X64-NEXT: # kill: def $cl killed $cl killed $rcx642; X64-NEXT: sarq %cl, %rax643; X64-NEXT: retq644 %val = load i64, ptr %valptr645 %negshamt = sub i64 64, %shamt646 %shifted = ashr i64 %val, %negshamt647 ret i64 %shifted648}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 %edi653; X86-NEXT: pushl %esi654; X86-NEXT: movl {{[0-9]+}}(%esp), %eax655; X86-NEXT: movl {{[0-9]+}}(%esp), %edx656; X86-NEXT: movl {{[0-9]+}}(%esp), %edi657; X86-NEXT: movb $64, %cl658; X86-NEXT: subb {{[0-9]+}}(%esp), %cl659; X86-NEXT: movl %edi, %esi660; X86-NEXT: sarl %cl, %esi661; X86-NEXT: shrdl %cl, %edi, %edx662; X86-NEXT: testb $32, %cl663; X86-NEXT: je .LBB22_2664; X86-NEXT: # %bb.1:665; X86-NEXT: sarl $31, %edi666; X86-NEXT: movl %esi, %edx667; X86-NEXT: movl %edi, %esi668; X86-NEXT: .LBB22_2:669; X86-NEXT: movl %esi, 4(%eax)670; X86-NEXT: movl %edx, (%eax)671; X86-NEXT: popl %esi672; X86-NEXT: popl %edi673; X86-NEXT: retl674;675; X64-LABEL: store64_ashr_by_negated:676; X64: # %bb.0:677; X64-NEXT: movq %rdx, %rcx678; X64-NEXT: negb %cl679; X64-NEXT: # kill: def $cl killed $cl killed $rcx680; X64-NEXT: sarq %cl, %rdi681; X64-NEXT: movq %rdi, (%rsi)682; X64-NEXT: retq683 %negshamt = sub i64 64, %shamt684 %shifted = ashr i64 %val, %negshamt685 store i64 %shifted, ptr %dstptr686 ret void687}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 %edi692; X86-NEXT: pushl %esi693; X86-NEXT: movl {{[0-9]+}}(%esp), %eax694; X86-NEXT: movl (%eax), %edx695; X86-NEXT: movl 4(%eax), %edi696; X86-NEXT: movb $64, %cl697; X86-NEXT: subb {{[0-9]+}}(%esp), %cl698; X86-NEXT: movl %edi, %esi699; X86-NEXT: sarl %cl, %esi700; X86-NEXT: shrdl %cl, %edi, %edx701; X86-NEXT: testb $32, %cl702; X86-NEXT: je .LBB23_2703; X86-NEXT: # %bb.1:704; X86-NEXT: sarl $31, %edi705; X86-NEXT: movl %esi, %edx706; X86-NEXT: movl %edi, %esi707; X86-NEXT: .LBB23_2:708; X86-NEXT: movl %edx, (%eax)709; X86-NEXT: movl %esi, 4(%eax)710; X86-NEXT: popl %esi711; X86-NEXT: popl %edi712; X86-NEXT: retl713;714; X64-LABEL: modify64_ashr_by_negated:715; X64: # %bb.0:716; X64-NEXT: movb $64, %cl717; X64-NEXT: subb %sil, %cl718; X64-NEXT: sarq %cl, (%rdi)719; X64-NEXT: retq720 %val = load i64, ptr %valptr721 %negshamt = sub i64 64, %shamt722 %shifted = ashr i64 %val, %negshamt723 store i64 %shifted, ptr %valptr724 ret void725}726 727;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;728; next let's only test simple reg pattern, and only lshr.729;||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||;730 731;==============================================================================;732; subtraction from negated shift amount733 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), %eax738; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx739; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx740; X86-NEXT: negb %cl741; X86-NEXT: # kill: def $cl killed $cl killed $ecx742; X86-NEXT: shrl %cl, %eax743; X86-NEXT: retl744;745; X64-LABEL: reg32_lshr_by_sub_from_negated:746; X64: # %bb.0:747; X64-NEXT: # kill: def $edx killed $edx def $rdx748; X64-NEXT: # kill: def $esi killed $esi def $rsi749; X64-NEXT: movl %edi, %eax750; X64-NEXT: leal (%rsi,%rdx), %ecx751; X64-NEXT: negb %cl752; X64-NEXT: # kill: def $cl killed $cl killed $ecx753; X64-NEXT: shrl %cl, %eax754; X64-NEXT: retq755 %nega = sub i32 32, %a756 %negasubb = sub i32 %nega, %b757 %shifted = lshr i32 %val, %negasubb758 ret i32 %shifted759}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 %esi764; X86-NEXT: movl {{[0-9]+}}(%esp), %eax765; X86-NEXT: movl {{[0-9]+}}(%esp), %esi766; X86-NEXT: movl {{[0-9]+}}(%esp), %edx767; X86-NEXT: addl {{[0-9]+}}(%esp), %edx768; X86-NEXT: movb $64, %cl769; X86-NEXT: subb %dl, %cl770; X86-NEXT: movl %esi, %edx771; X86-NEXT: shrl %cl, %edx772; X86-NEXT: shrdl %cl, %esi, %eax773; X86-NEXT: testb $32, %cl774; X86-NEXT: je .LBB25_2775; X86-NEXT: # %bb.1:776; X86-NEXT: movl %edx, %eax777; X86-NEXT: xorl %edx, %edx778; X86-NEXT: .LBB25_2:779; X86-NEXT: popl %esi780; X86-NEXT: retl781;782; X64-LABEL: reg64_lshr_by_sub_from_negated:783; X64: # %bb.0:784; X64-NEXT: movq %rdi, %rax785; X64-NEXT: leal (%rdx,%rsi), %ecx786; X64-NEXT: negb %cl787; X64-NEXT: # kill: def $cl killed $cl killed $ecx788; X64-NEXT: shrq %cl, %rax789; X64-NEXT: retq790 %nega = sub i64 64, %a791 %negasubb = sub i64 %nega, %b792 %shifted = lshr i64 %val, %negasubb793 ret i64 %shifted794}795 796;==============================================================================;797; subtraction of negated shift amount798 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), %eax803; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx804; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx805; X86-NEXT: # kill: def $cl killed $cl killed $ecx806; X86-NEXT: shrl %cl, %eax807; X86-NEXT: retl808;809; X64-LABEL: reg32_lshr_by_sub_of_negated:810; X64: # %bb.0:811; X64-NEXT: # kill: def $edx killed $edx def $rdx812; X64-NEXT: # kill: def $esi killed $esi def $rsi813; X64-NEXT: movl %edi, %eax814; X64-NEXT: leal (%rsi,%rdx), %ecx815; X64-NEXT: # kill: def $cl killed $cl killed $ecx816; X64-NEXT: shrl %cl, %eax817; X64-NEXT: retq818 %nega = sub i32 32, %a819 %negasubb = sub i32 %b, %nega820 %shifted = lshr i32 %val, %negasubb821 ret i32 %shifted822}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 %esi827; X86-NEXT: movl {{[0-9]+}}(%esp), %eax828; X86-NEXT: movl {{[0-9]+}}(%esp), %esi829; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx830; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx831; X86-NEXT: addb $-64, %cl832; X86-NEXT: movl %esi, %edx833; X86-NEXT: shrl %cl, %edx834; X86-NEXT: shrdl %cl, %esi, %eax835; X86-NEXT: testb $32, %cl836; X86-NEXT: je .LBB27_2837; X86-NEXT: # %bb.1:838; X86-NEXT: movl %edx, %eax839; X86-NEXT: xorl %edx, %edx840; X86-NEXT: .LBB27_2:841; X86-NEXT: popl %esi842; X86-NEXT: retl843;844; X64-LABEL: reg64_lshr_by_sub_of_negated:845; X64: # %bb.0:846; X64-NEXT: movq %rdi, %rax847; X64-NEXT: leal (%rdx,%rsi), %ecx848; X64-NEXT: # kill: def $cl killed $cl killed $ecx849; X64-NEXT: shrq %cl, %rax850; X64-NEXT: retq851 %nega = sub i64 64, %a852 %negasubb = sub i64 %b, %nega853 %shifted = lshr i64 %val, %negasubb854 ret i64 %shifted855}856 857;==============================================================================;858; add to negated shift amount859;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), %eax865; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx866; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx867; X86-NEXT: # kill: def $cl killed $cl killed $ecx868; X86-NEXT: shrl %cl, %eax869; X86-NEXT: retl870;871; X64-LABEL: reg32_lshr_by_add_to_negated:872; X64: # %bb.0:873; X64-NEXT: movl %edx, %ecx874; X64-NEXT: movl %edi, %eax875; X64-NEXT: subl %esi, %ecx876; X64-NEXT: # kill: def $cl killed $cl killed $ecx877; X64-NEXT: shrl %cl, %eax878; X64-NEXT: retq879 %nega = sub i32 32, %a880 %negasubb = add i32 %nega, %b881 %shifted = lshr i32 %val, %negasubb882 ret i32 %shifted883}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 %esi888; X86-NEXT: movl {{[0-9]+}}(%esp), %eax889; X86-NEXT: movl {{[0-9]+}}(%esp), %esi890; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx891; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx892; X86-NEXT: addb $64, %cl893; X86-NEXT: movl %esi, %edx894; X86-NEXT: shrl %cl, %edx895; X86-NEXT: shrdl %cl, %esi, %eax896; X86-NEXT: testb $32, %cl897; X86-NEXT: je .LBB29_2898; X86-NEXT: # %bb.1:899; X86-NEXT: movl %edx, %eax900; X86-NEXT: xorl %edx, %edx901; X86-NEXT: .LBB29_2:902; X86-NEXT: popl %esi903; X86-NEXT: retl904;905; X64-LABEL: reg64_lshr_by_add_to_negated:906; X64: # %bb.0:907; X64-NEXT: movq %rdx, %rcx908; X64-NEXT: movq %rdi, %rax909; X64-NEXT: subl %esi, %ecx910; X64-NEXT: # kill: def $cl killed $cl killed $rcx911; X64-NEXT: shrq %cl, %rax912; X64-NEXT: retq913 %nega = sub i64 64, %a914 %negasubb = add i64 %nega, %b915 %shifted = lshr i64 %val, %negasubb916 ret i64 %shifted917}918 919;==============================================================================;920; subtraction of negated shift amounts921 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), %eax926; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx927; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx928; X86-NEXT: # kill: def $cl killed $cl killed $ecx929; X86-NEXT: shrl %cl, %eax930; X86-NEXT: retl931;932; X64-LABEL: reg32_lshr_by_sub_of_negated_amts:933; X64: # %bb.0:934; X64-NEXT: movl %edx, %ecx935; X64-NEXT: movl %edi, %eax936; X64-NEXT: subl %esi, %ecx937; X64-NEXT: # kill: def $cl killed $cl killed $ecx938; X64-NEXT: shrl %cl, %eax939; X64-NEXT: retq940 %nega = sub i32 32, %a941 %negb = sub i32 32, %b942 %negasubnegb = sub i32 %nega, %negb943 %shifted = lshr i32 %val, %negasubnegb944 ret i32 %shifted945}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 %esi950; X86-NEXT: movl {{[0-9]+}}(%esp), %eax951; X86-NEXT: movl {{[0-9]+}}(%esp), %esi952; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx953; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx954; X86-NEXT: movl %esi, %edx955; X86-NEXT: shrl %cl, %edx956; X86-NEXT: shrdl %cl, %esi, %eax957; X86-NEXT: testb $32, %cl958; X86-NEXT: je .LBB31_2959; X86-NEXT: # %bb.1:960; X86-NEXT: movl %edx, %eax961; X86-NEXT: xorl %edx, %edx962; X86-NEXT: .LBB31_2:963; X86-NEXT: popl %esi964; X86-NEXT: retl965;966; X64-LABEL: reg64_lshr_by_sub_of_negated_amts:967; X64: # %bb.0:968; X64-NEXT: movq %rdx, %rcx969; X64-NEXT: movq %rdi, %rax970; X64-NEXT: subl %esi, %ecx971; X64-NEXT: # kill: def $cl killed $cl killed $rcx972; X64-NEXT: shrq %cl, %rax973; X64-NEXT: retq974 %nega = sub i64 64, %a975 %negb = sub i64 64, %b976 %negasubnegb = sub i64 %nega, %negb977 %shifted = lshr i64 %val, %negasubnegb978 ret i64 %shifted979}980 981;==============================================================================;982; addition of negated shift amounts983 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), %eax988; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx989; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx990; X86-NEXT: negb %cl991; X86-NEXT: # kill: def $cl killed $cl killed $ecx992; X86-NEXT: shrl %cl, %eax993; X86-NEXT: retl994;995; X64-LABEL: reg32_lshr_by_add_of_negated_amts:996; X64: # %bb.0:997; X64-NEXT: # kill: def $edx killed $edx def $rdx998; X64-NEXT: # kill: def $esi killed $esi def $rsi999; X64-NEXT: movl %edi, %eax1000; X64-NEXT: leal (%rsi,%rdx), %ecx1001; X64-NEXT: negb %cl1002; X64-NEXT: # kill: def $cl killed $cl killed $ecx1003; X64-NEXT: shrl %cl, %eax1004; X64-NEXT: retq1005 %nega = sub i32 32, %a1006 %negb = sub i32 32, %b1007 %negasubnegb = add i32 %nega, %negb1008 %shifted = lshr i32 %val, %negasubnegb1009 ret i32 %shifted1010}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 %esi1015; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1016; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1017; X86-NEXT: movl {{[0-9]+}}(%esp), %edx1018; X86-NEXT: addl {{[0-9]+}}(%esp), %edx1019; X86-NEXT: movb $-128, %cl1020; X86-NEXT: subb %dl, %cl1021; X86-NEXT: movl %esi, %edx1022; X86-NEXT: shrl %cl, %edx1023; X86-NEXT: shrdl %cl, %esi, %eax1024; X86-NEXT: testb $32, %cl1025; X86-NEXT: je .LBB33_21026; X86-NEXT: # %bb.1:1027; X86-NEXT: movl %edx, %eax1028; X86-NEXT: xorl %edx, %edx1029; X86-NEXT: .LBB33_2:1030; X86-NEXT: popl %esi1031; X86-NEXT: retl1032;1033; X64-LABEL: reg64_lshr_by_add_of_negated_amts:1034; X64: # %bb.0:1035; X64-NEXT: movq %rdi, %rax1036; X64-NEXT: leal (%rdx,%rsi), %ecx1037; X64-NEXT: negb %cl1038; X64-NEXT: # kill: def $cl killed $cl killed $ecx1039; X64-NEXT: shrq %cl, %rax1040; X64-NEXT: retq1041 %nega = sub i64 64, %a1042 %negb = sub i64 64, %b1043 %negasubnegb = add i64 %nega, %negb1044 %shifted = lshr i64 %val, %negasubnegb1045 ret i64 %shifted1046}1047 1048;==============================================================================;1049; and patterns with an actual negation+addition1050 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), %eax1055; X86-NEXT: xorl %ecx, %ecx1056; X86-NEXT: subb {{[0-9]+}}(%esp), %cl1057; X86-NEXT: # kill: def $cl killed $cl killed $ecx1058; X86-NEXT: shrl %cl, %eax1059; X86-NEXT: retl1060;1061; X64-LABEL: reg32_lshr_by_negated_unfolded:1062; X64: # %bb.0:1063; X64-NEXT: movl %esi, %ecx1064; X64-NEXT: movl %edi, %eax1065; X64-NEXT: negb %cl1066; X64-NEXT: # kill: def $cl killed $cl killed $ecx1067; X64-NEXT: shrl %cl, %eax1068; X64-NEXT: retq1069 %negshamt = sub i32 0, %shamt1070 %negaaddbitwidth = add i32 %negshamt, 321071 %shifted = lshr i32 %val, %negaaddbitwidth1072 ret i32 %shifted1073}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 %esi1078; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1079; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1080; X86-NEXT: movb $64, %cl1081; X86-NEXT: subb {{[0-9]+}}(%esp), %cl1082; X86-NEXT: movl %esi, %edx1083; X86-NEXT: shrl %cl, %edx1084; X86-NEXT: shrdl %cl, %esi, %eax1085; X86-NEXT: testb $32, %cl1086; X86-NEXT: je .LBB35_21087; X86-NEXT: # %bb.1:1088; X86-NEXT: movl %edx, %eax1089; X86-NEXT: xorl %edx, %edx1090; X86-NEXT: .LBB35_2:1091; X86-NEXT: popl %esi1092; X86-NEXT: retl1093;1094; X64-LABEL: reg64_lshr_by_negated_unfolded:1095; X64: # %bb.0:1096; X64-NEXT: movq %rsi, %rcx1097; X64-NEXT: movq %rdi, %rax1098; X64-NEXT: negb %cl1099; X64-NEXT: # kill: def $cl killed $cl killed $rcx1100; X64-NEXT: shrq %cl, %rax1101; X64-NEXT: retq1102 %negshamt = sub i64 0, %shamt1103 %negaaddbitwidth = add i64 %negshamt, 641104 %shifted = lshr i64 %val, %negaaddbitwidth1105 ret i64 %shifted1106}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), %eax1112; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1113; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx1114; X86-NEXT: negb %cl1115; X86-NEXT: # kill: def $cl killed $cl killed $ecx1116; X86-NEXT: shrl %cl, %eax1117; X86-NEXT: retl1118;1119; X64-LABEL: reg32_lshr_by_negated_unfolded_sub_b:1120; X64: # %bb.0:1121; X64-NEXT: # kill: def $edx killed $edx def $rdx1122; X64-NEXT: # kill: def $esi killed $esi def $rsi1123; X64-NEXT: movl %edi, %eax1124; X64-NEXT: leal (%rsi,%rdx), %ecx1125; X64-NEXT: negb %cl1126; X64-NEXT: # kill: def $cl killed $cl killed $ecx1127; X64-NEXT: shrl %cl, %eax1128; X64-NEXT: retq1129 %nega = sub i32 0, %a1130 %negaaddbitwidth = add i32 %nega, 321131 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b1132 %shifted = lshr i32 %val, %negaaddbitwidthsubb1133 ret i32 %shifted1134}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 %esi1139; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1140; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1141; X86-NEXT: movl {{[0-9]+}}(%esp), %edx1142; X86-NEXT: addl {{[0-9]+}}(%esp), %edx1143; X86-NEXT: movb $64, %cl1144; X86-NEXT: subb %dl, %cl1145; X86-NEXT: movl %esi, %edx1146; X86-NEXT: shrl %cl, %edx1147; X86-NEXT: shrdl %cl, %esi, %eax1148; X86-NEXT: testb $32, %cl1149; X86-NEXT: je .LBB37_21150; X86-NEXT: # %bb.1:1151; X86-NEXT: movl %edx, %eax1152; X86-NEXT: xorl %edx, %edx1153; X86-NEXT: .LBB37_2:1154; X86-NEXT: popl %esi1155; X86-NEXT: retl1156;1157; X64-LABEL: reg64_lshr_by_negated_unfolded_sub_b:1158; X64: # %bb.0:1159; X64-NEXT: movq %rdi, %rax1160; X64-NEXT: leal (%rdx,%rsi), %ecx1161; X64-NEXT: negb %cl1162; X64-NEXT: # kill: def $cl killed $cl killed $ecx1163; X64-NEXT: shrq %cl, %rax1164; X64-NEXT: retq1165 %nega = sub i64 0, %a1166 %negaaddbitwidth = add i64 %nega, 641167 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b1168 %shifted = lshr i64 %val, %negaaddbitwidthsubb1169 ret i64 %shifted1170}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), %eax1176; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1177; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx1178; X86-NEXT: # kill: def $cl killed $cl killed $ecx1179; X86-NEXT: shrl %cl, %eax1180; X86-NEXT: retl1181;1182; X64-LABEL: reg32_lshr_by_b_sub_negated_unfolded:1183; X64: # %bb.0:1184; X64-NEXT: # kill: def $edx killed $edx def $rdx1185; X64-NEXT: # kill: def $esi killed $esi def $rsi1186; X64-NEXT: movl %edi, %eax1187; X64-NEXT: leal (%rsi,%rdx), %ecx1188; X64-NEXT: # kill: def $cl killed $cl killed $ecx1189; X64-NEXT: shrl %cl, %eax1190; X64-NEXT: retq1191 %nega = sub i32 0, %a1192 %negaaddbitwidth = add i32 %nega, 321193 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth1194 %shifted = lshr i32 %val, %negaaddbitwidthsubb1195 ret i32 %shifted1196}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 %esi1201; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1202; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1203; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1204; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx1205; X86-NEXT: addb $-64, %cl1206; X86-NEXT: movl %esi, %edx1207; X86-NEXT: shrl %cl, %edx1208; X86-NEXT: shrdl %cl, %esi, %eax1209; X86-NEXT: testb $32, %cl1210; X86-NEXT: je .LBB39_21211; X86-NEXT: # %bb.1:1212; X86-NEXT: movl %edx, %eax1213; X86-NEXT: xorl %edx, %edx1214; X86-NEXT: .LBB39_2:1215; X86-NEXT: popl %esi1216; X86-NEXT: retl1217;1218; X64-LABEL: reg64_lshr_by_b_sub_negated_unfolded:1219; X64: # %bb.0:1220; X64-NEXT: movq %rdi, %rax1221; X64-NEXT: leal (%rdx,%rsi), %ecx1222; X64-NEXT: # kill: def $cl killed $cl killed $ecx1223; X64-NEXT: shrq %cl, %rax1224; X64-NEXT: retq1225 %nega = sub i64 0, %a1226 %negaaddbitwidth = add i64 %nega, 641227 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth1228 %shifted = lshr i64 %val, %negaaddbitwidthsubb1229 ret i64 %shifted1230}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), %eax1236; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1237; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1238; X86-NEXT: # kill: def $cl killed $cl killed $ecx1239; X86-NEXT: shrl %cl, %eax1240; X86-NEXT: retl1241;1242; X64-LABEL: reg32_lshr_by_negated_unfolded_add_b:1243; X64: # %bb.0:1244; X64-NEXT: movl %edx, %ecx1245; X64-NEXT: movl %edi, %eax1246; X64-NEXT: subl %esi, %ecx1247; X64-NEXT: # kill: def $cl killed $cl killed $ecx1248; X64-NEXT: shrl %cl, %eax1249; X64-NEXT: retq1250 %nega = sub i32 0, %a1251 %negaaddbitwidth = add i32 %nega, 321252 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b1253 %shifted = lshr i32 %val, %negaaddbitwidthaddb1254 ret i32 %shifted1255}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 %esi1260; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1261; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1262; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1263; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1264; X86-NEXT: addb $64, %cl1265; X86-NEXT: movl %esi, %edx1266; X86-NEXT: shrl %cl, %edx1267; X86-NEXT: shrdl %cl, %esi, %eax1268; X86-NEXT: testb $32, %cl1269; X86-NEXT: je .LBB41_21270; X86-NEXT: # %bb.1:1271; X86-NEXT: movl %edx, %eax1272; X86-NEXT: xorl %edx, %edx1273; X86-NEXT: .LBB41_2:1274; X86-NEXT: popl %esi1275; X86-NEXT: retl1276;1277; X64-LABEL: reg64_lshr_by_negated_unfolded_add_b:1278; X64: # %bb.0:1279; X64-NEXT: movq %rdx, %rcx1280; X64-NEXT: movq %rdi, %rax1281; X64-NEXT: subl %esi, %ecx1282; X64-NEXT: # kill: def $cl killed $cl killed $rcx1283; X64-NEXT: shrq %cl, %rax1284; X64-NEXT: retq1285 %nega = sub i64 0, %a1286 %negaaddbitwidth = add i64 %nega, 641287 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b1288 %shifted = lshr i64 %val, %negaaddbitwidthaddb1289 ret i64 %shifted1290}1291 1292;==============================================================================;1293; and patterns with an actual negation+mask1294 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), %eax1299; X86-NEXT: xorl %ecx, %ecx1300; X86-NEXT: subb {{[0-9]+}}(%esp), %cl1301; X86-NEXT: # kill: def $cl killed $cl killed $ecx1302; X86-NEXT: shrl %cl, %eax1303; X86-NEXT: retl1304;1305; X64-LABEL: reg32_lshr_by_masked_negated_unfolded:1306; X64: # %bb.0:1307; X64-NEXT: movl %esi, %ecx1308; X64-NEXT: movl %edi, %eax1309; X64-NEXT: negb %cl1310; X64-NEXT: # kill: def $cl killed $cl killed $ecx1311; X64-NEXT: shrl %cl, %eax1312; X64-NEXT: retq1313 %negshamt = sub i32 0, %shamt1314 %negaaddbitwidth = and i32 %negshamt, 311315 %shifted = lshr i32 %val, %negaaddbitwidth1316 ret i32 %shifted1317}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 %esi1322; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1323; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1324; X86-NEXT: xorl %ecx, %ecx1325; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx1326; X86-NEXT: subb %dl, %cl1327; X86-NEXT: movl %esi, %edx1328; X86-NEXT: shrl %cl, %edx1329; X86-NEXT: shrdl %cl, %esi, %eax1330; X86-NEXT: testb $32, %cl1331; X86-NEXT: je .LBB43_21332; X86-NEXT: # %bb.1:1333; X86-NEXT: movl %edx, %eax1334; X86-NEXT: xorl %edx, %edx1335; X86-NEXT: .LBB43_2:1336; X86-NEXT: popl %esi1337; X86-NEXT: retl1338;1339; X64-LABEL: reg64_lshr_by_masked_negated_unfolded:1340; X64: # %bb.0:1341; X64-NEXT: movq %rsi, %rcx1342; X64-NEXT: movq %rdi, %rax1343; X64-NEXT: negb %cl1344; X64-NEXT: # kill: def $cl killed $cl killed $rcx1345; X64-NEXT: shrq %cl, %rax1346; X64-NEXT: retq1347 %negshamt = sub i64 0, %shamt1348 %negaaddbitwidth = and i64 %negshamt, 631349 %shifted = lshr i64 %val, %negaaddbitwidth1350 ret i64 %shifted1351}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), %eax1357; X86-NEXT: xorl %ecx, %ecx1358; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1359; X86-NEXT: andl $31, %ecx1360; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1361; X86-NEXT: # kill: def $cl killed $cl killed $ecx1362; X86-NEXT: shrl %cl, %eax1363; X86-NEXT: retl1364;1365; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_sub_b:1366; X64: # %bb.0:1367; X64-NEXT: movl %esi, %ecx1368; X64-NEXT: movl %edi, %eax1369; X64-NEXT: negl %ecx1370; X64-NEXT: andl $31, %ecx1371; X64-NEXT: subl %edx, %ecx1372; X64-NEXT: # kill: def $cl killed $cl killed $ecx1373; X64-NEXT: shrl %cl, %eax1374; X64-NEXT: retq1375 %nega = sub i32 0, %a1376 %negaaddbitwidth = and i32 %nega, 311377 %negaaddbitwidthsubb = sub i32 %negaaddbitwidth, %b1378 %shifted = lshr i32 %val, %negaaddbitwidthsubb1379 ret i32 %shifted1380}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 %esi1385; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1386; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1387; X86-NEXT: xorl %ecx, %ecx1388; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1389; X86-NEXT: andl $63, %ecx1390; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1391; X86-NEXT: movl %esi, %edx1392; X86-NEXT: shrl %cl, %edx1393; X86-NEXT: shrdl %cl, %esi, %eax1394; X86-NEXT: testb $32, %cl1395; X86-NEXT: je .LBB45_21396; X86-NEXT: # %bb.1:1397; X86-NEXT: movl %edx, %eax1398; X86-NEXT: xorl %edx, %edx1399; X86-NEXT: .LBB45_2:1400; X86-NEXT: popl %esi1401; X86-NEXT: retl1402;1403; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_sub_b:1404; X64: # %bb.0:1405; X64-NEXT: movq %rsi, %rcx1406; X64-NEXT: movq %rdi, %rax1407; X64-NEXT: negl %ecx1408; X64-NEXT: andl $63, %ecx1409; X64-NEXT: subl %edx, %ecx1410; X64-NEXT: # kill: def $cl killed $cl killed $rcx1411; X64-NEXT: shrq %cl, %rax1412; X64-NEXT: retq1413 %nega = sub i64 0, %a1414 %negaaddbitwidth = and i64 %nega, 631415 %negaaddbitwidthsubb = sub i64 %negaaddbitwidth, %b1416 %shifted = lshr i64 %val, %negaaddbitwidthsubb1417 ret i64 %shifted1418}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), %eax1424; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1425; X86-NEXT: xorl %edx, %edx1426; X86-NEXT: subl {{[0-9]+}}(%esp), %edx1427; X86-NEXT: andl $31, %edx1428; X86-NEXT: subl %edx, %ecx1429; X86-NEXT: # kill: def $cl killed $cl killed $ecx1430; X86-NEXT: shrl %cl, %eax1431; X86-NEXT: retl1432;1433; X64-LABEL: reg32_lshr_by_masked_b_sub_negated_unfolded:1434; X64: # %bb.0:1435; X64-NEXT: movl %edx, %ecx1436; X64-NEXT: movl %edi, %eax1437; X64-NEXT: negl %esi1438; X64-NEXT: andl $31, %esi1439; X64-NEXT: subl %esi, %ecx1440; X64-NEXT: # kill: def $cl killed $cl killed $ecx1441; X64-NEXT: shrl %cl, %eax1442; X64-NEXT: retq1443 %nega = sub i32 0, %a1444 %negaaddbitwidth = and i32 %nega, 311445 %negaaddbitwidthsubb = sub i32 %b, %negaaddbitwidth1446 %shifted = lshr i32 %val, %negaaddbitwidthsubb1447 ret i32 %shifted1448}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 %esi1453; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1454; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1455; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1456; X86-NEXT: xorl %edx, %edx1457; X86-NEXT: subl {{[0-9]+}}(%esp), %edx1458; X86-NEXT: andl $63, %edx1459; X86-NEXT: subl %edx, %ecx1460; X86-NEXT: movl %esi, %edx1461; X86-NEXT: shrl %cl, %edx1462; X86-NEXT: shrdl %cl, %esi, %eax1463; X86-NEXT: testb $32, %cl1464; X86-NEXT: je .LBB47_21465; X86-NEXT: # %bb.1:1466; X86-NEXT: movl %edx, %eax1467; X86-NEXT: xorl %edx, %edx1468; X86-NEXT: .LBB47_2:1469; X86-NEXT: popl %esi1470; X86-NEXT: retl1471;1472; X64-LABEL: reg64_lshr_by_masked_b_sub_negated_unfolded:1473; X64: # %bb.0:1474; X64-NEXT: movq %rdx, %rcx1475; X64-NEXT: movq %rdi, %rax1476; X64-NEXT: negl %esi1477; X64-NEXT: andl $63, %esi1478; X64-NEXT: subl %esi, %ecx1479; X64-NEXT: # kill: def $cl killed $cl killed $rcx1480; X64-NEXT: shrq %cl, %rax1481; X64-NEXT: retq1482 %nega = sub i64 0, %a1483 %negaaddbitwidth = and i64 %nega, 631484 %negaaddbitwidthsubb = sub i64 %b, %negaaddbitwidth1485 %shifted = lshr i64 %val, %negaaddbitwidthsubb1486 ret i64 %shifted1487}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), %eax1493; X86-NEXT: xorl %ecx, %ecx1494; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1495; X86-NEXT: andl $31, %ecx1496; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx1497; X86-NEXT: # kill: def $cl killed $cl killed $ecx1498; X86-NEXT: shrl %cl, %eax1499; X86-NEXT: retl1500;1501; X64-LABEL: reg32_lshr_by_masked_negated_unfolded_add_b:1502; X64: # %bb.0:1503; X64-NEXT: # kill: def $edx killed $edx def $rdx1504; X64-NEXT: # kill: def $esi killed $esi def $rsi1505; X64-NEXT: movl %edi, %eax1506; X64-NEXT: negl %esi1507; X64-NEXT: andl $31, %esi1508; X64-NEXT: leal (%rsi,%rdx), %ecx1509; X64-NEXT: # kill: def $cl killed $cl killed $ecx1510; X64-NEXT: shrl %cl, %eax1511; X64-NEXT: retq1512 %nega = sub i32 0, %a1513 %negaaddbitwidth = and i32 %nega, 311514 %negaaddbitwidthaddb = add i32 %negaaddbitwidth, %b1515 %shifted = lshr i32 %val, %negaaddbitwidthaddb1516 ret i32 %shifted1517}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 %esi1522; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1523; X86-NEXT: movl {{[0-9]+}}(%esp), %esi1524; X86-NEXT: xorl %ecx, %ecx1525; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx1526; X86-NEXT: andl $63, %ecx1527; X86-NEXT: addl {{[0-9]+}}(%esp), %ecx1528; X86-NEXT: movl %esi, %edx1529; X86-NEXT: shrl %cl, %edx1530; X86-NEXT: shrdl %cl, %esi, %eax1531; X86-NEXT: testb $32, %cl1532; X86-NEXT: je .LBB49_21533; X86-NEXT: # %bb.1:1534; X86-NEXT: movl %edx, %eax1535; X86-NEXT: xorl %edx, %edx1536; X86-NEXT: .LBB49_2:1537; X86-NEXT: popl %esi1538; X86-NEXT: retl1539;1540; X64-LABEL: reg64_lshr_by_masked_negated_unfolded_add_b:1541; X64: # %bb.0:1542; X64-NEXT: movq %rdi, %rax1543; X64-NEXT: negl %esi1544; X64-NEXT: andl $63, %esi1545; X64-NEXT: leal (%rdx,%rsi), %ecx1546; X64-NEXT: # kill: def $cl killed $cl killed $ecx1547; X64-NEXT: shrq %cl, %rax1548; X64-NEXT: retq1549 %nega = sub i64 0, %a1550 %negaaddbitwidth = and i64 %nega, 631551 %negaaddbitwidthaddb = add i64 %negaaddbitwidth, %b1552 %shifted = lshr i64 %val, %negaaddbitwidthaddb1553 ret i64 %shifted1554}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), %eax1560; X86-NEXT: shrl $4, %eax1561; X86-NEXT: andl $15, %eax1562; X86-NEXT: # kill: def $ax killed $ax killed $eax1563; X86-NEXT: retl1564;1565; X64-LABEL: sh_trunc_sh:1566; X64: # %bb.0:1567; X64-NEXT: movq %rdi, %rax1568; X64-NEXT: shrq $36, %rax1569; X64-NEXT: andl $15, %eax1570; X64-NEXT: # kill: def $ax killed $ax killed $rax1571; X64-NEXT: retq1572 %s = lshr i64 %x, 241573 %t = trunc i64 %s to i161574 %r = lshr i16 %t, 121575 ret i16 %r1576}1577