659 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-prefixes=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X644 5; Check that we recognize this idiom for rotation too:6; a << (b & (OpSize-1)) | a >> ((0 - b) & (OpSize-1))7 8define i32 @rotate_left_32(i32 %a, i32 %b) {9; X86-LABEL: rotate_left_32:10; X86: # %bb.0:11; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx12; X86-NEXT: movl {{[0-9]+}}(%esp), %eax13; X86-NEXT: roll %cl, %eax14; X86-NEXT: retl15;16; X64-LABEL: rotate_left_32:17; X64: # %bb.0:18; X64-NEXT: movl %esi, %ecx19; X64-NEXT: movl %edi, %eax20; X64-NEXT: # kill: def $cl killed $cl killed $ecx21; X64-NEXT: roll %cl, %eax22; X64-NEXT: retq23 %and = and i32 %b, 3124 %shl = shl i32 %a, %and25 %t0 = sub i32 0, %b26 %and3 = and i32 %t0, 3127 %shr = lshr i32 %a, %and328 %or = or i32 %shl, %shr29 ret i32 %or30}31 32define i32 @rotate_right_32(i32 %a, i32 %b) {33; X86-LABEL: rotate_right_32:34; X86: # %bb.0:35; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx36; X86-NEXT: movl {{[0-9]+}}(%esp), %eax37; X86-NEXT: rorl %cl, %eax38; X86-NEXT: retl39;40; X64-LABEL: rotate_right_32:41; X64: # %bb.0:42; X64-NEXT: movl %esi, %ecx43; X64-NEXT: movl %edi, %eax44; X64-NEXT: # kill: def $cl killed $cl killed $ecx45; X64-NEXT: rorl %cl, %eax46; X64-NEXT: retq47 %and = and i32 %b, 3148 %shl = lshr i32 %a, %and49 %t0 = sub i32 0, %b50 %and3 = and i32 %t0, 3151 %shr = shl i32 %a, %and352 %or = or i32 %shl, %shr53 ret i32 %or54}55 56define i64 @rotate_left_64(i64 %a, i64 %b) {57; X86-LABEL: rotate_left_64:58; X86: # %bb.0:59; X86-NEXT: pushl %ebx60; X86-NEXT: .cfi_def_cfa_offset 861; X86-NEXT: pushl %edi62; X86-NEXT: .cfi_def_cfa_offset 1263; X86-NEXT: pushl %esi64; X86-NEXT: .cfi_def_cfa_offset 1665; X86-NEXT: .cfi_offset %esi, -1666; X86-NEXT: .cfi_offset %edi, -1267; X86-NEXT: .cfi_offset %ebx, -868; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx69; X86-NEXT: movl {{[0-9]+}}(%esp), %esi70; X86-NEXT: movl {{[0-9]+}}(%esp), %edi71; X86-NEXT: movl %esi, %eax72; X86-NEXT: shll %cl, %eax73; X86-NEXT: movl %edi, %edx74; X86-NEXT: shldl %cl, %esi, %edx75; X86-NEXT: testb $32, %cl76; X86-NEXT: je .LBB2_277; X86-NEXT: # %bb.1:78; X86-NEXT: movl %eax, %edx79; X86-NEXT: xorl %eax, %eax80; X86-NEXT: .LBB2_2:81; X86-NEXT: negb %cl82; X86-NEXT: movl %edi, %ebx83; X86-NEXT: shrl %cl, %ebx84; X86-NEXT: shrdl %cl, %edi, %esi85; X86-NEXT: testb $32, %cl86; X86-NEXT: je .LBB2_487; X86-NEXT: # %bb.3:88; X86-NEXT: movl %ebx, %esi89; X86-NEXT: xorl %ebx, %ebx90; X86-NEXT: .LBB2_4:91; X86-NEXT: orl %ebx, %edx92; X86-NEXT: orl %esi, %eax93; X86-NEXT: popl %esi94; X86-NEXT: .cfi_def_cfa_offset 1295; X86-NEXT: popl %edi96; X86-NEXT: .cfi_def_cfa_offset 897; X86-NEXT: popl %ebx98; X86-NEXT: .cfi_def_cfa_offset 499; X86-NEXT: retl100;101; X64-LABEL: rotate_left_64:102; X64: # %bb.0:103; X64-NEXT: movq %rsi, %rcx104; X64-NEXT: movq %rdi, %rax105; X64-NEXT: # kill: def $cl killed $cl killed $rcx106; X64-NEXT: rolq %cl, %rax107; X64-NEXT: retq108 %and = and i64 %b, 63109 %shl = shl i64 %a, %and110 %t0 = sub i64 0, %b111 %and3 = and i64 %t0, 63112 %shr = lshr i64 %a, %and3113 %or = or i64 %shl, %shr114 ret i64 %or115}116 117define i64 @rotate_right_64(i64 %a, i64 %b) {118; X86-LABEL: rotate_right_64:119; X86: # %bb.0:120; X86-NEXT: pushl %ebx121; X86-NEXT: .cfi_def_cfa_offset 8122; X86-NEXT: pushl %edi123; X86-NEXT: .cfi_def_cfa_offset 12124; X86-NEXT: pushl %esi125; X86-NEXT: .cfi_def_cfa_offset 16126; X86-NEXT: .cfi_offset %esi, -16127; X86-NEXT: .cfi_offset %edi, -12128; X86-NEXT: .cfi_offset %ebx, -8129; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx130; X86-NEXT: movl {{[0-9]+}}(%esp), %edi131; X86-NEXT: movl {{[0-9]+}}(%esp), %esi132; X86-NEXT: movl %esi, %edx133; X86-NEXT: shrl %cl, %edx134; X86-NEXT: movl %edi, %eax135; X86-NEXT: shrdl %cl, %esi, %eax136; X86-NEXT: testb $32, %cl137; X86-NEXT: je .LBB3_2138; X86-NEXT: # %bb.1:139; X86-NEXT: movl %edx, %eax140; X86-NEXT: xorl %edx, %edx141; X86-NEXT: .LBB3_2:142; X86-NEXT: negb %cl143; X86-NEXT: movl %edi, %ebx144; X86-NEXT: shll %cl, %ebx145; X86-NEXT: shldl %cl, %edi, %esi146; X86-NEXT: testb $32, %cl147; X86-NEXT: je .LBB3_4148; X86-NEXT: # %bb.3:149; X86-NEXT: movl %ebx, %esi150; X86-NEXT: xorl %ebx, %ebx151; X86-NEXT: .LBB3_4:152; X86-NEXT: orl %esi, %edx153; X86-NEXT: orl %ebx, %eax154; X86-NEXT: popl %esi155; X86-NEXT: .cfi_def_cfa_offset 12156; X86-NEXT: popl %edi157; X86-NEXT: .cfi_def_cfa_offset 8158; X86-NEXT: popl %ebx159; X86-NEXT: .cfi_def_cfa_offset 4160; X86-NEXT: retl161;162; X64-LABEL: rotate_right_64:163; X64: # %bb.0:164; X64-NEXT: movq %rsi, %rcx165; X64-NEXT: movq %rdi, %rax166; X64-NEXT: # kill: def $cl killed $cl killed $rcx167; X64-NEXT: rorq %cl, %rax168; X64-NEXT: retq169 %and = and i64 %b, 63170 %shl = lshr i64 %a, %and171 %t0 = sub i64 0, %b172 %and3 = and i64 %t0, 63173 %shr = shl i64 %a, %and3174 %or = or i64 %shl, %shr175 ret i64 %or176}177 178; Also check mem operand.179 180define void @rotate_left_m32(ptr%pa, i32 %b) {181; X86-LABEL: rotate_left_m32:182; X86: # %bb.0:183; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx184; X86-NEXT: movl {{[0-9]+}}(%esp), %eax185; X86-NEXT: roll %cl, (%eax)186; X86-NEXT: retl187;188; X64-LABEL: rotate_left_m32:189; X64: # %bb.0:190; X64-NEXT: movl %esi, %ecx191; X64-NEXT: # kill: def $cl killed $cl killed $ecx192; X64-NEXT: roll %cl, (%rdi)193; X64-NEXT: retq194 %a = load i32, ptr %pa, align 16195 %and = and i32 %b, 31196 %shl = shl i32 %a, %and197 %t0 = sub i32 0, %b198 %and3 = and i32 %t0, 31199 %shr = lshr i32 %a, %and3200 %or = or i32 %shl, %shr201 store i32 %or, ptr %pa, align 32202 ret void203}204 205define void @rotate_right_m32(ptr%pa, i32 %b) {206; X86-LABEL: rotate_right_m32:207; X86: # %bb.0:208; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx209; X86-NEXT: movl {{[0-9]+}}(%esp), %eax210; X86-NEXT: rorl %cl, (%eax)211; X86-NEXT: retl212;213; X64-LABEL: rotate_right_m32:214; X64: # %bb.0:215; X64-NEXT: movl %esi, %ecx216; X64-NEXT: # kill: def $cl killed $cl killed $ecx217; X64-NEXT: rorl %cl, (%rdi)218; X64-NEXT: retq219 %a = load i32, ptr %pa, align 16220 %and = and i32 %b, 31221 %shl = lshr i32 %a, %and222 %t0 = sub i32 0, %b223 %and3 = and i32 %t0, 31224 %shr = shl i32 %a, %and3225 %or = or i32 %shl, %shr226 store i32 %or, ptr %pa, align 32227 ret void228}229 230define void @rotate_left_m64(ptr%pa, i64 %b) {231; X86-LABEL: rotate_left_m64:232; X86: # %bb.0:233; X86-NEXT: pushl %ebp234; X86-NEXT: .cfi_def_cfa_offset 8235; X86-NEXT: pushl %ebx236; X86-NEXT: .cfi_def_cfa_offset 12237; X86-NEXT: pushl %edi238; X86-NEXT: .cfi_def_cfa_offset 16239; X86-NEXT: pushl %esi240; X86-NEXT: .cfi_def_cfa_offset 20241; X86-NEXT: .cfi_offset %esi, -20242; X86-NEXT: .cfi_offset %edi, -16243; X86-NEXT: .cfi_offset %ebx, -12244; X86-NEXT: .cfi_offset %ebp, -8245; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx246; X86-NEXT: movl {{[0-9]+}}(%esp), %eax247; X86-NEXT: movl (%eax), %esi248; X86-NEXT: movl 4(%eax), %ebx249; X86-NEXT: movl %esi, %edx250; X86-NEXT: shll %cl, %edx251; X86-NEXT: movl %ebx, %edi252; X86-NEXT: shldl %cl, %esi, %edi253; X86-NEXT: testb $32, %cl254; X86-NEXT: je .LBB6_2255; X86-NEXT: # %bb.1:256; X86-NEXT: movl %edx, %edi257; X86-NEXT: xorl %edx, %edx258; X86-NEXT: .LBB6_2:259; X86-NEXT: negb %cl260; X86-NEXT: movl %ebx, %ebp261; X86-NEXT: shrl %cl, %ebp262; X86-NEXT: shrdl %cl, %ebx, %esi263; X86-NEXT: testb $32, %cl264; X86-NEXT: je .LBB6_4265; X86-NEXT: # %bb.3:266; X86-NEXT: movl %ebp, %esi267; X86-NEXT: xorl %ebp, %ebp268; X86-NEXT: .LBB6_4:269; X86-NEXT: orl %esi, %edx270; X86-NEXT: orl %ebp, %edi271; X86-NEXT: movl %edx, (%eax)272; X86-NEXT: movl %edi, 4(%eax)273; X86-NEXT: popl %esi274; X86-NEXT: .cfi_def_cfa_offset 16275; X86-NEXT: popl %edi276; X86-NEXT: .cfi_def_cfa_offset 12277; X86-NEXT: popl %ebx278; X86-NEXT: .cfi_def_cfa_offset 8279; X86-NEXT: popl %ebp280; X86-NEXT: .cfi_def_cfa_offset 4281; X86-NEXT: retl282;283; X64-LABEL: rotate_left_m64:284; X64: # %bb.0:285; X64-NEXT: movq %rsi, %rcx286; X64-NEXT: # kill: def $cl killed $cl killed $rcx287; X64-NEXT: rolq %cl, (%rdi)288; X64-NEXT: retq289 %a = load i64, ptr %pa, align 16290 %and = and i64 %b, 63291 %shl = shl i64 %a, %and292 %t0 = sub i64 0, %b293 %and3 = and i64 %t0, 63294 %shr = lshr i64 %a, %and3295 %or = or i64 %shl, %shr296 store i64 %or, ptr %pa, align 64297 ret void298}299 300define void @rotate_right_m64(ptr%pa, i64 %b) {301; X86-LABEL: rotate_right_m64:302; X86: # %bb.0:303; X86-NEXT: pushl %ebp304; X86-NEXT: .cfi_def_cfa_offset 8305; X86-NEXT: pushl %ebx306; X86-NEXT: .cfi_def_cfa_offset 12307; X86-NEXT: pushl %edi308; X86-NEXT: .cfi_def_cfa_offset 16309; X86-NEXT: pushl %esi310; X86-NEXT: .cfi_def_cfa_offset 20311; X86-NEXT: .cfi_offset %esi, -20312; X86-NEXT: .cfi_offset %edi, -16313; X86-NEXT: .cfi_offset %ebx, -12314; X86-NEXT: .cfi_offset %ebp, -8315; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx316; X86-NEXT: movl {{[0-9]+}}(%esp), %eax317; X86-NEXT: movl (%eax), %ebx318; X86-NEXT: movl 4(%eax), %esi319; X86-NEXT: movl %esi, %edx320; X86-NEXT: shrl %cl, %edx321; X86-NEXT: movl %ebx, %edi322; X86-NEXT: shrdl %cl, %esi, %edi323; X86-NEXT: testb $32, %cl324; X86-NEXT: je .LBB7_2325; X86-NEXT: # %bb.1:326; X86-NEXT: movl %edx, %edi327; X86-NEXT: xorl %edx, %edx328; X86-NEXT: .LBB7_2:329; X86-NEXT: negb %cl330; X86-NEXT: movl %ebx, %ebp331; X86-NEXT: shll %cl, %ebp332; X86-NEXT: shldl %cl, %ebx, %esi333; X86-NEXT: testb $32, %cl334; X86-NEXT: je .LBB7_4335; X86-NEXT: # %bb.3:336; X86-NEXT: movl %ebp, %esi337; X86-NEXT: xorl %ebp, %ebp338; X86-NEXT: .LBB7_4:339; X86-NEXT: orl %ebp, %edi340; X86-NEXT: orl %esi, %edx341; X86-NEXT: movl %edi, (%eax)342; X86-NEXT: movl %edx, 4(%eax)343; X86-NEXT: popl %esi344; X86-NEXT: .cfi_def_cfa_offset 16345; X86-NEXT: popl %edi346; X86-NEXT: .cfi_def_cfa_offset 12347; X86-NEXT: popl %ebx348; X86-NEXT: .cfi_def_cfa_offset 8349; X86-NEXT: popl %ebp350; X86-NEXT: .cfi_def_cfa_offset 4351; X86-NEXT: retl352;353; X64-LABEL: rotate_right_m64:354; X64: # %bb.0:355; X64-NEXT: movq %rsi, %rcx356; X64-NEXT: # kill: def $cl killed $cl killed $rcx357; X64-NEXT: rorq %cl, (%rdi)358; X64-NEXT: retq359 %a = load i64, ptr %pa, align 16360 %and = and i64 %b, 63361 %shl = lshr i64 %a, %and362 %t0 = sub i64 0, %b363 %and3 = and i64 %t0, 63364 %shr = shl i64 %a, %and3365 %or = or i64 %shl, %shr366 store i64 %or, ptr %pa, align 64367 ret void368}369 370; The next 8 tests include masks of the narrow width shift amounts that should be eliminated.371; These patterns are produced by instcombine after r310509.372 373define i8 @rotate_left_8(i8 %x, i32 %amount) {374; X86-LABEL: rotate_left_8:375; X86: # %bb.0:376; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx377; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax378; X86-NEXT: rolb %cl, %al379; X86-NEXT: retl380;381; X64-LABEL: rotate_left_8:382; X64: # %bb.0:383; X64-NEXT: movl %esi, %ecx384; X64-NEXT: movl %edi, %eax385; X64-NEXT: # kill: def $cl killed $cl killed $ecx386; X64-NEXT: rolb %cl, %al387; X64-NEXT: # kill: def $al killed $al killed $eax388; X64-NEXT: retq389 %amt = trunc i32 %amount to i8390 %sub = sub i8 0, %amt391 %maskamt = and i8 %amt, 7392 %masksub = and i8 %sub, 7393 %shl = shl i8 %x, %maskamt394 %shr = lshr i8 %x, %masksub395 %or = or i8 %shl, %shr396 ret i8 %or397}398 399define i8 @rotate_right_8(i8 %x, i32 %amount) {400; X86-LABEL: rotate_right_8:401; X86: # %bb.0:402; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx403; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax404; X86-NEXT: rorb %cl, %al405; X86-NEXT: retl406;407; X64-LABEL: rotate_right_8:408; X64: # %bb.0:409; X64-NEXT: movl %esi, %ecx410; X64-NEXT: movl %edi, %eax411; X64-NEXT: # kill: def $cl killed $cl killed $ecx412; X64-NEXT: rorb %cl, %al413; X64-NEXT: # kill: def $al killed $al killed $eax414; X64-NEXT: retq415 %amt = trunc i32 %amount to i8416 %sub = sub i8 0, %amt417 %maskamt = and i8 %amt, 7418 %masksub = and i8 %sub, 7419 %shr = lshr i8 %x, %maskamt420 %shl = shl i8 %x, %masksub421 %or = or i8 %shr, %shl422 ret i8 %or423}424 425define i16 @rotate_left_16(i16 %x, i32 %amount) {426; X86-LABEL: rotate_left_16:427; X86: # %bb.0:428; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx429; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax430; X86-NEXT: rolw %cl, %ax431; X86-NEXT: retl432;433; X64-LABEL: rotate_left_16:434; X64: # %bb.0:435; X64-NEXT: movl %esi, %ecx436; X64-NEXT: movl %edi, %eax437; X64-NEXT: # kill: def $cl killed $cl killed $ecx438; X64-NEXT: rolw %cl, %ax439; X64-NEXT: # kill: def $ax killed $ax killed $eax440; X64-NEXT: retq441 %amt = trunc i32 %amount to i16442 %sub = sub i16 0, %amt443 %maskamt = and i16 %amt, 15444 %masksub = and i16 %sub, 15445 %shl = shl i16 %x, %maskamt446 %shr = lshr i16 %x, %masksub447 %or = or i16 %shl, %shr448 ret i16 %or449}450 451define i16 @rotate_right_16(i16 %x, i32 %amount) {452; X86-LABEL: rotate_right_16:453; X86: # %bb.0:454; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx455; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax456; X86-NEXT: rorw %cl, %ax457; X86-NEXT: retl458;459; X64-LABEL: rotate_right_16:460; X64: # %bb.0:461; X64-NEXT: movl %esi, %ecx462; X64-NEXT: movl %edi, %eax463; X64-NEXT: # kill: def $cl killed $cl killed $ecx464; X64-NEXT: rorw %cl, %ax465; X64-NEXT: # kill: def $ax killed $ax killed $eax466; X64-NEXT: retq467 %amt = trunc i32 %amount to i16468 %sub = sub i16 0, %amt469 %maskamt = and i16 %amt, 15470 %masksub = and i16 %sub, 15471 %shr = lshr i16 %x, %maskamt472 %shl = shl i16 %x, %masksub473 %or = or i16 %shr, %shl474 ret i16 %or475}476 477define void @rotate_left_m8(ptr %p, i32 %amount) {478; X86-LABEL: rotate_left_m8:479; X86: # %bb.0:480; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx481; X86-NEXT: movl {{[0-9]+}}(%esp), %eax482; X86-NEXT: rolb %cl, (%eax)483; X86-NEXT: retl484;485; X64-LABEL: rotate_left_m8:486; X64: # %bb.0:487; X64-NEXT: movl %esi, %ecx488; X64-NEXT: # kill: def $cl killed $cl killed $ecx489; X64-NEXT: rolb %cl, (%rdi)490; X64-NEXT: retq491 %x = load i8, ptr %p, align 1492 %amt = trunc i32 %amount to i8493 %sub = sub i8 0, %amt494 %maskamt = and i8 %amt, 7495 %masksub = and i8 %sub, 7496 %shl = shl i8 %x, %maskamt497 %shr = lshr i8 %x, %masksub498 %or = or i8 %shl, %shr499 store i8 %or, ptr %p, align 1500 ret void501}502 503define void @rotate_right_m8(ptr %p, i32 %amount) {504; X86-LABEL: rotate_right_m8:505; X86: # %bb.0:506; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx507; X86-NEXT: movl {{[0-9]+}}(%esp), %eax508; X86-NEXT: rorb %cl, (%eax)509; X86-NEXT: retl510;511; X64-LABEL: rotate_right_m8:512; X64: # %bb.0:513; X64-NEXT: movl %esi, %ecx514; X64-NEXT: # kill: def $cl killed $cl killed $ecx515; X64-NEXT: rorb %cl, (%rdi)516; X64-NEXT: retq517 %x = load i8, ptr %p, align 1518 %amt = trunc i32 %amount to i8519 %sub = sub i8 0, %amt520 %maskamt = and i8 %amt, 7521 %masksub = and i8 %sub, 7522 %shl = shl i8 %x, %masksub523 %shr = lshr i8 %x, %maskamt524 %or = or i8 %shl, %shr525 store i8 %or, ptr %p, align 1526 ret void527}528 529define void @rotate_left_m16(ptr %p, i32 %amount) {530; X86-LABEL: rotate_left_m16:531; X86: # %bb.0:532; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx533; X86-NEXT: movl {{[0-9]+}}(%esp), %eax534; X86-NEXT: rolw %cl, (%eax)535; X86-NEXT: retl536;537; X64-LABEL: rotate_left_m16:538; X64: # %bb.0:539; X64-NEXT: movl %esi, %ecx540; X64-NEXT: # kill: def $cl killed $cl killed $ecx541; X64-NEXT: rolw %cl, (%rdi)542; X64-NEXT: retq543 %x = load i16, ptr %p, align 1544 %amt = trunc i32 %amount to i16545 %sub = sub i16 0, %amt546 %maskamt = and i16 %amt, 15547 %masksub = and i16 %sub, 15548 %shl = shl i16 %x, %maskamt549 %shr = lshr i16 %x, %masksub550 %or = or i16 %shl, %shr551 store i16 %or, ptr %p, align 1552 ret void553}554 555define void @rotate_right_m16(ptr %p, i32 %amount) {556; X86-LABEL: rotate_right_m16:557; X86: # %bb.0:558; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx559; X86-NEXT: movl {{[0-9]+}}(%esp), %eax560; X86-NEXT: rorw %cl, (%eax)561; X86-NEXT: retl562;563; X64-LABEL: rotate_right_m16:564; X64: # %bb.0:565; X64-NEXT: movl %esi, %ecx566; X64-NEXT: # kill: def $cl killed $cl killed $ecx567; X64-NEXT: rorw %cl, (%rdi)568; X64-NEXT: retq569 %x = load i16, ptr %p, align 1570 %amt = trunc i32 %amount to i16571 %sub = sub i16 0, %amt572 %maskamt = and i16 %amt, 15573 %masksub = and i16 %sub, 15574 %shl = shl i16 %x, %masksub575 %shr = lshr i16 %x, %maskamt576 %or = or i16 %shl, %shr577 store i16 %or, ptr %p, align 1578 ret void579}580 581define i32 @rotate_demanded_bits(i32, i32) {582; X86-LABEL: rotate_demanded_bits:583; X86: # %bb.0:584; X86-NEXT: movl {{[0-9]+}}(%esp), %eax585; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx586; X86-NEXT: andb $30, %cl587; X86-NEXT: roll %cl, %eax588; X86-NEXT: retl589;590; X64-LABEL: rotate_demanded_bits:591; X64: # %bb.0:592; X64-NEXT: movl %esi, %ecx593; X64-NEXT: movl %edi, %eax594; X64-NEXT: andb $30, %cl595; X64-NEXT: # kill: def $cl killed $cl killed $ecx596; X64-NEXT: roll %cl, %eax597; X64-NEXT: retq598 %3 = and i32 %1, 30599 %4 = shl i32 %0, %3600 %5 = sub nsw i32 0, %3601 %6 = and i32 %5, 30602 %7 = lshr i32 %0, %6603 %8 = or i32 %7, %4604 ret i32 %8605}606 607define i32 @rotate_demanded_bits_2(i32, i32) {608; X86-LABEL: rotate_demanded_bits_2:609; X86: # %bb.0:610; X86-NEXT: movl {{[0-9]+}}(%esp), %eax611; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx612; X86-NEXT: andb $23, %cl613; X86-NEXT: roll %cl, %eax614; X86-NEXT: retl615;616; X64-LABEL: rotate_demanded_bits_2:617; X64: # %bb.0:618; X64-NEXT: movl %esi, %ecx619; X64-NEXT: movl %edi, %eax620; X64-NEXT: andb $23, %cl621; X64-NEXT: # kill: def $cl killed $cl killed $ecx622; X64-NEXT: roll %cl, %eax623; X64-NEXT: retq624 %3 = and i32 %1, 23625 %4 = shl i32 %0, %3626 %5 = sub nsw i32 0, %3627 %6 = and i32 %5, 31628 %7 = lshr i32 %0, %6629 %8 = or i32 %7, %4630 ret i32 %8631}632 633define i32 @rotate_demanded_bits_3(i32, i32) {634; X86-LABEL: rotate_demanded_bits_3:635; X86: # %bb.0:636; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx637; X86-NEXT: addb %cl, %cl638; X86-NEXT: movl {{[0-9]+}}(%esp), %eax639; X86-NEXT: roll %cl, %eax640; X86-NEXT: retl641;642; X64-LABEL: rotate_demanded_bits_3:643; X64: # %bb.0:644; X64-NEXT: # kill: def $esi killed $esi def $rsi645; X64-NEXT: movl %edi, %eax646; X64-NEXT: leal (%rsi,%rsi), %ecx647; X64-NEXT: # kill: def $cl killed $cl killed $ecx648; X64-NEXT: roll %cl, %eax649; X64-NEXT: retq650 %3 = shl i32 %1, 1651 %4 = and i32 %3, 30652 %5 = shl i32 %0, %4653 %6 = sub i32 0, %3654 %7 = and i32 %6, 30655 %8 = lshr i32 %0, %7656 %9 = or i32 %5, %8657 ret i32 %9658}659