1118 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s --check-prefix=X643; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s --check-prefix=X864 5; FIXME: We don't match this properly due to different size of 'rotate' and 'and'6define i16 @btr_16(i16 %x, i16 %n) {7; X64-LABEL: btr_16:8; X64: # %bb.0:9; X64-NEXT: movl %esi, %ecx10; X64-NEXT: movw $-2, %ax11; X64-NEXT: # kill: def $cl killed $cl killed $ecx12; X64-NEXT: rolw %cl, %ax13; X64-NEXT: andl %edi, %eax14; X64-NEXT: # kill: def $ax killed $ax killed $eax15; X64-NEXT: retq16;17; X86-LABEL: btr_16:18; X86: # %bb.0:19; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax20; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx21; X86-NEXT: btrw %cx, %ax22; X86-NEXT: retl23 %1 = shl i16 1, %n24 %2 = xor i16 %1, -125 %3 = and i16 %x, %226 ret i16 %327}28 29define i16 @bts_16(i16 %x, i16 %n) {30; X64-LABEL: bts_16:31; X64: # %bb.0:32; X64-NEXT: movl %edi, %eax33; X64-NEXT: btsl %esi, %eax34; X64-NEXT: # kill: def $ax killed $ax killed $eax35; X64-NEXT: retq36;37; X86-LABEL: bts_16:38; X86: # %bb.0:39; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx40; X86-NEXT: movl $1, %eax41; X86-NEXT: shll %cl, %eax42; X86-NEXT: orw {{[0-9]+}}(%esp), %ax43; X86-NEXT: # kill: def $ax killed $ax killed $eax44; X86-NEXT: retl45 %1 = shl i16 1, %n46 %2 = or i16 %x, %147 ret i16 %248}49 50define i16 @btc_16(i16 %x, i16 %n) {51; X64-LABEL: btc_16:52; X64: # %bb.0:53; X64-NEXT: movl %edi, %eax54; X64-NEXT: btcl %esi, %eax55; X64-NEXT: # kill: def $ax killed $ax killed $eax56; X64-NEXT: retq57;58; X86-LABEL: btc_16:59; X86: # %bb.0:60; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx61; X86-NEXT: movl $1, %eax62; X86-NEXT: shll %cl, %eax63; X86-NEXT: xorw {{[0-9]+}}(%esp), %ax64; X86-NEXT: # kill: def $ax killed $ax killed $eax65; X86-NEXT: retl66 %1 = shl i16 1, %n67 %2 = xor i16 %x, %168 ret i16 %269}70 71define i32 @btr_32(i32 %x, i32 %n) {72; X64-LABEL: btr_32:73; X64: # %bb.0:74; X64-NEXT: movl %edi, %eax75; X64-NEXT: btrl %esi, %eax76; X64-NEXT: retq77;78; X86-LABEL: btr_32:79; X86: # %bb.0:80; X86-NEXT: movl {{[0-9]+}}(%esp), %eax81; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx82; X86-NEXT: btrl %ecx, %eax83; X86-NEXT: retl84 %1 = shl i32 1, %n85 %2 = xor i32 %1, -186 %3 = and i32 %x, %287 ret i32 %388}89 90define i32 @bts_32(i32 %x, i32 %n) {91; X64-LABEL: bts_32:92; X64: # %bb.0:93; X64-NEXT: movl %edi, %eax94; X64-NEXT: btsl %esi, %eax95; X64-NEXT: retq96;97; X86-LABEL: bts_32:98; X86: # %bb.0:99; X86-NEXT: movl {{[0-9]+}}(%esp), %eax100; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx101; X86-NEXT: btsl %ecx, %eax102; X86-NEXT: retl103 %1 = shl i32 1, %n104 %2 = or i32 %x, %1105 ret i32 %2106}107 108define i32 @btc_32(i32 %x, i32 %n) {109; X64-LABEL: btc_32:110; X64: # %bb.0:111; X64-NEXT: movl %edi, %eax112; X64-NEXT: btcl %esi, %eax113; X64-NEXT: retq114;115; X86-LABEL: btc_32:116; X86: # %bb.0:117; X86-NEXT: movl {{[0-9]+}}(%esp), %eax118; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx119; X86-NEXT: btcl %ecx, %eax120; X86-NEXT: retl121 %1 = shl i32 1, %n122 %2 = xor i32 %x, %1123 ret i32 %2124}125 126define i64 @btr_64(i64 %x, i64 %n) {127; X64-LABEL: btr_64:128; X64: # %bb.0:129; X64-NEXT: movq %rdi, %rax130; X64-NEXT: btrq %rsi, %rax131; X64-NEXT: retq132;133; X86-LABEL: btr_64:134; X86: # %bb.0:135; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx136; X86-NEXT: movl $1, %eax137; X86-NEXT: xorl %edx, %edx138; X86-NEXT: shldl %cl, %eax, %edx139; X86-NEXT: shll %cl, %eax140; X86-NEXT: testb $32, %cl141; X86-NEXT: je .LBB6_2142; X86-NEXT: # %bb.1:143; X86-NEXT: movl %eax, %edx144; X86-NEXT: xorl %eax, %eax145; X86-NEXT: .LBB6_2:146; X86-NEXT: notl %edx147; X86-NEXT: notl %eax148; X86-NEXT: andl {{[0-9]+}}(%esp), %edx149; X86-NEXT: andl {{[0-9]+}}(%esp), %eax150; X86-NEXT: retl151 %1 = shl i64 1, %n152 %2 = xor i64 %1, -1153 %3 = and i64 %x, %2154 ret i64 %3155}156 157define i64 @bts_64(i64 %x, i64 %n) {158; X64-LABEL: bts_64:159; X64: # %bb.0:160; X64-NEXT: movq %rdi, %rax161; X64-NEXT: btsq %rsi, %rax162; X64-NEXT: retq163;164; X86-LABEL: bts_64:165; X86: # %bb.0:166; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx167; X86-NEXT: movl $1, %eax168; X86-NEXT: xorl %edx, %edx169; X86-NEXT: shldl %cl, %eax, %edx170; X86-NEXT: shll %cl, %eax171; X86-NEXT: testb $32, %cl172; X86-NEXT: je .LBB7_2173; X86-NEXT: # %bb.1:174; X86-NEXT: movl %eax, %edx175; X86-NEXT: xorl %eax, %eax176; X86-NEXT: .LBB7_2:177; X86-NEXT: orl {{[0-9]+}}(%esp), %edx178; X86-NEXT: orl {{[0-9]+}}(%esp), %eax179; X86-NEXT: retl180 %1 = shl i64 1, %n181 %2 = or i64 %x, %1182 ret i64 %2183}184 185define i64 @btc_64(i64 %x, i64 %n) {186; X64-LABEL: btc_64:187; X64: # %bb.0:188; X64-NEXT: movq %rdi, %rax189; X64-NEXT: btcq %rsi, %rax190; X64-NEXT: retq191;192; X86-LABEL: btc_64:193; X86: # %bb.0:194; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx195; X86-NEXT: movl $1, %eax196; X86-NEXT: xorl %edx, %edx197; X86-NEXT: shldl %cl, %eax, %edx198; X86-NEXT: shll %cl, %eax199; X86-NEXT: testb $32, %cl200; X86-NEXT: je .LBB8_2201; X86-NEXT: # %bb.1:202; X86-NEXT: movl %eax, %edx203; X86-NEXT: xorl %eax, %eax204; X86-NEXT: .LBB8_2:205; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx206; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax207; X86-NEXT: retl208 %1 = shl i64 1, %n209 %2 = xor i64 %x, %1210 ret i64 %2211}212 213define i16 @btr_16_mask(i16 %x, i16 %n) {214; X64-LABEL: btr_16_mask:215; X64: # %bb.0:216; X64-NEXT: movl %esi, %ecx217; X64-NEXT: movw $-2, %ax218; X64-NEXT: # kill: def $cl killed $cl killed $ecx219; X64-NEXT: rolw %cl, %ax220; X64-NEXT: andl %edi, %eax221; X64-NEXT: # kill: def $ax killed $ax killed $eax222; X64-NEXT: retq223;224; X86-LABEL: btr_16_mask:225; X86: # %bb.0:226; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax227; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx228; X86-NEXT: btrw %cx, %ax229; X86-NEXT: retl230 %1 = and i16 %n, 15231 %2 = shl i16 1, %1232 %3 = xor i16 %2, -1233 %4 = and i16 %x, %3234 ret i16 %4235}236 237define i16 @bts_16_mask(i16 %x, i16 %n) {238; X64-LABEL: bts_16_mask:239; X64: # %bb.0:240; X64-NEXT: movl %edi, %eax241; X64-NEXT: andb $15, %sil242; X64-NEXT: btsl %esi, %eax243; X64-NEXT: # kill: def $ax killed $ax killed $eax244; X64-NEXT: retq245;246; X86-LABEL: bts_16_mask:247; X86: # %bb.0:248; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx249; X86-NEXT: andb $15, %cl250; X86-NEXT: movl $1, %eax251; X86-NEXT: shll %cl, %eax252; X86-NEXT: orw {{[0-9]+}}(%esp), %ax253; X86-NEXT: # kill: def $ax killed $ax killed $eax254; X86-NEXT: retl255 %1 = and i16 %n, 15256 %2 = shl i16 1, %1257 %3 = or i16 %x, %2258 ret i16 %3259}260 261define i16 @btc_16_mask(i16 %x, i16 %n) {262; X64-LABEL: btc_16_mask:263; X64: # %bb.0:264; X64-NEXT: movl %edi, %eax265; X64-NEXT: andb $15, %sil266; X64-NEXT: btcl %esi, %eax267; X64-NEXT: # kill: def $ax killed $ax killed $eax268; X64-NEXT: retq269;270; X86-LABEL: btc_16_mask:271; X86: # %bb.0:272; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx273; X86-NEXT: andb $15, %cl274; X86-NEXT: movl $1, %eax275; X86-NEXT: shll %cl, %eax276; X86-NEXT: xorw {{[0-9]+}}(%esp), %ax277; X86-NEXT: # kill: def $ax killed $ax killed $eax278; X86-NEXT: retl279 %1 = and i16 %n, 15280 %2 = shl i16 1, %1281 %3 = xor i16 %x, %2282 ret i16 %3283}284 285define i32 @btr_32_mask(i32 %x, i32 %n) {286; X64-LABEL: btr_32_mask:287; X64: # %bb.0:288; X64-NEXT: movl %edi, %eax289; X64-NEXT: btrl %esi, %eax290; X64-NEXT: retq291;292; X86-LABEL: btr_32_mask:293; X86: # %bb.0:294; X86-NEXT: movl {{[0-9]+}}(%esp), %eax295; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx296; X86-NEXT: btrl %ecx, %eax297; X86-NEXT: retl298 %1 = and i32 %n, 31299 %2 = shl i32 1, %1300 %3 = xor i32 %2, -1301 %4 = and i32 %x, %3302 ret i32 %4303}304 305define i32 @bts_32_mask(i32 %x, i32 %n) {306; X64-LABEL: bts_32_mask:307; X64: # %bb.0:308; X64-NEXT: movl %edi, %eax309; X64-NEXT: btsl %esi, %eax310; X64-NEXT: retq311;312; X86-LABEL: bts_32_mask:313; X86: # %bb.0:314; X86-NEXT: movl {{[0-9]+}}(%esp), %eax315; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx316; X86-NEXT: btsl %ecx, %eax317; X86-NEXT: retl318 %1 = and i32 %n, 31319 %2 = shl i32 1, %1320 %3 = or i32 %x, %2321 ret i32 %3322}323 324define i32 @btc_32_mask(i32 %x, i32 %n) {325; X64-LABEL: btc_32_mask:326; X64: # %bb.0:327; X64-NEXT: movl %edi, %eax328; X64-NEXT: btcl %esi, %eax329; X64-NEXT: retq330;331; X86-LABEL: btc_32_mask:332; X86: # %bb.0:333; X86-NEXT: movl {{[0-9]+}}(%esp), %eax334; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx335; X86-NEXT: btcl %ecx, %eax336; X86-NEXT: retl337 %1 = and i32 %n, 31338 %2 = shl i32 1, %1339 %3 = xor i32 %x, %2340 ret i32 %3341}342 343define i64 @btr_64_mask(i64 %x, i64 %n) {344; X64-LABEL: btr_64_mask:345; X64: # %bb.0:346; X64-NEXT: movq %rdi, %rax347; X64-NEXT: btrq %rsi, %rax348; X64-NEXT: retq349;350; X86-LABEL: btr_64_mask:351; X86: # %bb.0:352; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx353; X86-NEXT: movl $1, %eax354; X86-NEXT: xorl %edx, %edx355; X86-NEXT: shldl %cl, %eax, %edx356; X86-NEXT: shll %cl, %eax357; X86-NEXT: testb $32, %cl358; X86-NEXT: je .LBB15_2359; X86-NEXT: # %bb.1:360; X86-NEXT: movl %eax, %edx361; X86-NEXT: xorl %eax, %eax362; X86-NEXT: .LBB15_2:363; X86-NEXT: notl %edx364; X86-NEXT: notl %eax365; X86-NEXT: andl {{[0-9]+}}(%esp), %edx366; X86-NEXT: andl {{[0-9]+}}(%esp), %eax367; X86-NEXT: retl368 %1 = and i64 %n, 63369 %2 = shl i64 1, %1370 %3 = xor i64 %2, -1371 %4 = and i64 %x, %3372 ret i64 %4373}374 375define i64 @bts_64_mask(i64 %x, i64 %n) {376; X64-LABEL: bts_64_mask:377; X64: # %bb.0:378; X64-NEXT: movq %rdi, %rax379; X64-NEXT: btsq %rsi, %rax380; X64-NEXT: retq381;382; X86-LABEL: bts_64_mask:383; X86: # %bb.0:384; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx385; X86-NEXT: movl $1, %eax386; X86-NEXT: xorl %edx, %edx387; X86-NEXT: shldl %cl, %eax, %edx388; X86-NEXT: shll %cl, %eax389; X86-NEXT: testb $32, %cl390; X86-NEXT: je .LBB16_2391; X86-NEXT: # %bb.1:392; X86-NEXT: movl %eax, %edx393; X86-NEXT: xorl %eax, %eax394; X86-NEXT: .LBB16_2:395; X86-NEXT: orl {{[0-9]+}}(%esp), %edx396; X86-NEXT: orl {{[0-9]+}}(%esp), %eax397; X86-NEXT: retl398 %1 = and i64 %n, 63399 %2 = shl i64 1, %1400 %3 = or i64 %x, %2401 ret i64 %3402}403 404define i64 @btc_64_mask(i64 %x, i64 %n) {405; X64-LABEL: btc_64_mask:406; X64: # %bb.0:407; X64-NEXT: movq %rdi, %rax408; X64-NEXT: btcq %rsi, %rax409; X64-NEXT: retq410;411; X86-LABEL: btc_64_mask:412; X86: # %bb.0:413; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx414; X86-NEXT: movl $1, %eax415; X86-NEXT: xorl %edx, %edx416; X86-NEXT: shldl %cl, %eax, %edx417; X86-NEXT: shll %cl, %eax418; X86-NEXT: testb $32, %cl419; X86-NEXT: je .LBB17_2420; X86-NEXT: # %bb.1:421; X86-NEXT: movl %eax, %edx422; X86-NEXT: xorl %eax, %eax423; X86-NEXT: .LBB17_2:424; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx425; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax426; X86-NEXT: retl427 %1 = and i64 %n, 63428 %2 = shl i64 1, %1429 %3 = xor i64 %x, %2430 ret i64 %3431}432 433; Tests below use loads and we favor folding those over matching btc/btr/bts.434 435define i16 @btr_16_load(ptr %x, i16 %n) {436; X64-LABEL: btr_16_load:437; X64: # %bb.0:438; X64-NEXT: movzwl (%rdi), %eax439; X64-NEXT: btrw %si, %ax440; X64-NEXT: retq441;442; X86-LABEL: btr_16_load:443; X86: # %bb.0:444; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx445; X86-NEXT: movl {{[0-9]+}}(%esp), %eax446; X86-NEXT: movzwl (%eax), %eax447; X86-NEXT: btrw %cx, %ax448; X86-NEXT: retl449 %1 = load i16, ptr %x450 %2 = shl i16 1, %n451 %3 = xor i16 %2, -1452 %4 = and i16 %1, %3453 ret i16 %4454}455 456define i16 @bts_16_load(ptr %x, i16 %n) {457; X64-LABEL: bts_16_load:458; X64: # %bb.0:459; X64-NEXT: movl %esi, %ecx460; X64-NEXT: movl $1, %eax461; X64-NEXT: # kill: def $cl killed $cl killed $ecx462; X64-NEXT: shll %cl, %eax463; X64-NEXT: orw (%rdi), %ax464; X64-NEXT: # kill: def $ax killed $ax killed $eax465; X64-NEXT: retq466;467; X86-LABEL: bts_16_load:468; X86: # %bb.0:469; X86-NEXT: movl {{[0-9]+}}(%esp), %edx470; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx471; X86-NEXT: movl $1, %eax472; X86-NEXT: shll %cl, %eax473; X86-NEXT: orw (%edx), %ax474; X86-NEXT: # kill: def $ax killed $ax killed $eax475; X86-NEXT: retl476 %1 = load i16, ptr %x477 %2 = shl i16 1, %n478 %3 = or i16 %1, %2479 ret i16 %3480}481 482define i16 @btc_16_load(ptr %x, i16 %n) {483; X64-LABEL: btc_16_load:484; X64: # %bb.0:485; X64-NEXT: movl %esi, %ecx486; X64-NEXT: movl $1, %eax487; X64-NEXT: # kill: def $cl killed $cl killed $ecx488; X64-NEXT: shll %cl, %eax489; X64-NEXT: xorw (%rdi), %ax490; X64-NEXT: # kill: def $ax killed $ax killed $eax491; X64-NEXT: retq492;493; X86-LABEL: btc_16_load:494; X86: # %bb.0:495; X86-NEXT: movl {{[0-9]+}}(%esp), %edx496; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx497; X86-NEXT: movl $1, %eax498; X86-NEXT: shll %cl, %eax499; X86-NEXT: xorw (%edx), %ax500; X86-NEXT: # kill: def $ax killed $ax killed $eax501; X86-NEXT: retl502 %1 = load i16, ptr %x503 %2 = shl i16 1, %n504 %3 = xor i16 %1, %2505 ret i16 %3506}507 508define i32 @btr_32_load(ptr %x, i32 %n) {509; X64-LABEL: btr_32_load:510; X64: # %bb.0:511; X64-NEXT: movl (%rdi), %eax512; X64-NEXT: btrl %esi, %eax513; X64-NEXT: retq514;515; X86-LABEL: btr_32_load:516; X86: # %bb.0:517; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx518; X86-NEXT: movl {{[0-9]+}}(%esp), %eax519; X86-NEXT: movl (%eax), %eax520; X86-NEXT: btrl %ecx, %eax521; X86-NEXT: retl522 %1 = load i32, ptr %x523 %2 = shl i32 1, %n524 %3 = xor i32 %2, -1525 %4 = and i32 %1, %3526 ret i32 %4527}528 529define i32 @bts_32_load(ptr %x, i32 %n) {530; X64-LABEL: bts_32_load:531; X64: # %bb.0:532; X64-NEXT: movl (%rdi), %eax533; X64-NEXT: btsl %esi, %eax534; X64-NEXT: retq535;536; X86-LABEL: bts_32_load:537; X86: # %bb.0:538; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx539; X86-NEXT: movl {{[0-9]+}}(%esp), %eax540; X86-NEXT: movl (%eax), %eax541; X86-NEXT: btsl %ecx, %eax542; X86-NEXT: retl543 %1 = load i32, ptr %x544 %2 = shl i32 1, %n545 %3 = or i32 %1, %2546 ret i32 %3547}548 549define i32 @btc_32_load(ptr %x, i32 %n) {550; X64-LABEL: btc_32_load:551; X64: # %bb.0:552; X64-NEXT: movl (%rdi), %eax553; X64-NEXT: btcl %esi, %eax554; X64-NEXT: retq555;556; X86-LABEL: btc_32_load:557; X86: # %bb.0:558; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx559; X86-NEXT: movl {{[0-9]+}}(%esp), %eax560; X86-NEXT: movl (%eax), %eax561; X86-NEXT: btcl %ecx, %eax562; X86-NEXT: retl563 %1 = load i32, ptr %x564 %2 = shl i32 1, %n565 %3 = xor i32 %1, %2566 ret i32 %3567}568 569define i64 @btr_64_load(ptr %x, i64 %n) {570; X64-LABEL: btr_64_load:571; X64: # %bb.0:572; X64-NEXT: movq (%rdi), %rax573; X64-NEXT: btrq %rsi, %rax574; X64-NEXT: retq575;576; X86-LABEL: btr_64_load:577; X86: # %bb.0:578; X86-NEXT: pushl %esi579; X86-NEXT: .cfi_def_cfa_offset 8580; X86-NEXT: .cfi_offset %esi, -8581; X86-NEXT: movl {{[0-9]+}}(%esp), %esi582; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx583; X86-NEXT: movl $1, %eax584; X86-NEXT: xorl %edx, %edx585; X86-NEXT: shldl %cl, %eax, %edx586; X86-NEXT: shll %cl, %eax587; X86-NEXT: testb $32, %cl588; X86-NEXT: je .LBB24_2589; X86-NEXT: # %bb.1:590; X86-NEXT: movl %eax, %edx591; X86-NEXT: xorl %eax, %eax592; X86-NEXT: .LBB24_2:593; X86-NEXT: notl %edx594; X86-NEXT: notl %eax595; X86-NEXT: andl 4(%esi), %edx596; X86-NEXT: andl (%esi), %eax597; X86-NEXT: popl %esi598; X86-NEXT: .cfi_def_cfa_offset 4599; X86-NEXT: retl600 %1 = load i64, ptr %x601 %2 = shl i64 1, %n602 %3 = xor i64 %2, -1603 %4 = and i64 %1, %3604 ret i64 %4605}606 607define i64 @bts_64_load(ptr %x, i64 %n) {608; X64-LABEL: bts_64_load:609; X64: # %bb.0:610; X64-NEXT: movq (%rdi), %rax611; X64-NEXT: btsq %rsi, %rax612; X64-NEXT: retq613;614; X86-LABEL: bts_64_load:615; X86: # %bb.0:616; X86-NEXT: pushl %esi617; X86-NEXT: .cfi_def_cfa_offset 8618; X86-NEXT: .cfi_offset %esi, -8619; X86-NEXT: movl {{[0-9]+}}(%esp), %esi620; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx621; X86-NEXT: movl $1, %eax622; X86-NEXT: xorl %edx, %edx623; X86-NEXT: shldl %cl, %eax, %edx624; X86-NEXT: shll %cl, %eax625; X86-NEXT: testb $32, %cl626; X86-NEXT: je .LBB25_2627; X86-NEXT: # %bb.1:628; X86-NEXT: movl %eax, %edx629; X86-NEXT: xorl %eax, %eax630; X86-NEXT: .LBB25_2:631; X86-NEXT: orl 4(%esi), %edx632; X86-NEXT: orl (%esi), %eax633; X86-NEXT: popl %esi634; X86-NEXT: .cfi_def_cfa_offset 4635; X86-NEXT: retl636 %1 = load i64, ptr %x637 %2 = shl i64 1, %n638 %3 = or i64 %1, %2639 ret i64 %3640}641 642define i64 @btc_64_load(ptr %x, i64 %n) {643; X64-LABEL: btc_64_load:644; X64: # %bb.0:645; X64-NEXT: movq (%rdi), %rax646; X64-NEXT: btcq %rsi, %rax647; X64-NEXT: retq648;649; X86-LABEL: btc_64_load:650; X86: # %bb.0:651; X86-NEXT: pushl %esi652; X86-NEXT: .cfi_def_cfa_offset 8653; X86-NEXT: .cfi_offset %esi, -8654; X86-NEXT: movl {{[0-9]+}}(%esp), %esi655; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx656; X86-NEXT: movl $1, %eax657; X86-NEXT: xorl %edx, %edx658; X86-NEXT: shldl %cl, %eax, %edx659; X86-NEXT: shll %cl, %eax660; X86-NEXT: testb $32, %cl661; X86-NEXT: je .LBB26_2662; X86-NEXT: # %bb.1:663; X86-NEXT: movl %eax, %edx664; X86-NEXT: xorl %eax, %eax665; X86-NEXT: .LBB26_2:666; X86-NEXT: xorl 4(%esi), %edx667; X86-NEXT: xorl (%esi), %eax668; X86-NEXT: popl %esi669; X86-NEXT: .cfi_def_cfa_offset 4670; X86-NEXT: retl671 %1 = load i64, ptr %x672 %2 = shl i64 1, %n673 %3 = xor i64 %1, %2674 ret i64 %3675}676 677; For the tests below, we definitely shouldn't fold them to the memory forms678; of BTR/BTS/BTC as they have very different semantics from their register679; counterparts.680 681define void @btr_16_dont_fold(ptr %x, i16 %n) {682; X64-LABEL: btr_16_dont_fold:683; X64: # %bb.0:684; X64-NEXT: movl %esi, %ecx685; X64-NEXT: movw $-2, %ax686; X64-NEXT: # kill: def $cl killed $cl killed $ecx687; X64-NEXT: rolw %cl, %ax688; X64-NEXT: andw %ax, (%rdi)689; X64-NEXT: retq690;691; X86-LABEL: btr_16_dont_fold:692; X86: # %bb.0:693; X86-NEXT: movl {{[0-9]+}}(%esp), %eax694; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx695; X86-NEXT: movw $-2, %dx696; X86-NEXT: rolw %cl, %dx697; X86-NEXT: andw %dx, (%eax)698; X86-NEXT: retl699 %1 = load i16, ptr %x700 %2 = shl i16 1, %n701 %3 = xor i16 %2, -1702 %4 = and i16 %1, %3703 store i16 %4, ptr %x704 ret void705}706 707define void @bts_16_dont_fold(ptr %x, i16 %n) {708; X64-LABEL: bts_16_dont_fold:709; X64: # %bb.0:710; X64-NEXT: movl %esi, %ecx711; X64-NEXT: movl $1, %eax712; X64-NEXT: # kill: def $cl killed $cl killed $ecx713; X64-NEXT: shll %cl, %eax714; X64-NEXT: orw %ax, (%rdi)715; X64-NEXT: retq716;717; X86-LABEL: bts_16_dont_fold:718; X86: # %bb.0:719; X86-NEXT: movl {{[0-9]+}}(%esp), %eax720; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx721; X86-NEXT: movl $1, %edx722; X86-NEXT: shll %cl, %edx723; X86-NEXT: orw %dx, (%eax)724; X86-NEXT: retl725 %1 = load i16, ptr %x726 %2 = shl i16 1, %n727 %3 = or i16 %1, %2728 store i16 %3, ptr %x729 ret void730}731 732define void @btc_16_dont_fold(ptr %x, i16 %n) {733; X64-LABEL: btc_16_dont_fold:734; X64: # %bb.0:735; X64-NEXT: movl %esi, %ecx736; X64-NEXT: movl $1, %eax737; X64-NEXT: # kill: def $cl killed $cl killed $ecx738; X64-NEXT: shll %cl, %eax739; X64-NEXT: xorw %ax, (%rdi)740; X64-NEXT: retq741;742; X86-LABEL: btc_16_dont_fold:743; X86: # %bb.0:744; X86-NEXT: movl {{[0-9]+}}(%esp), %eax745; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx746; X86-NEXT: movl $1, %edx747; X86-NEXT: shll %cl, %edx748; X86-NEXT: xorw %dx, (%eax)749; X86-NEXT: retl750 %1 = load i16, ptr %x751 %2 = shl i16 1, %n752 %3 = xor i16 %1, %2753 store i16 %3, ptr %x754 ret void755}756 757define void @btr_32_dont_fold(ptr %x, i32 %n) {758; X64-LABEL: btr_32_dont_fold:759; X64: # %bb.0:760; X64-NEXT: movl %esi, %ecx761; X64-NEXT: movl $-2, %eax762; X64-NEXT: # kill: def $cl killed $cl killed $ecx763; X64-NEXT: roll %cl, %eax764; X64-NEXT: andl %eax, (%rdi)765; X64-NEXT: retq766;767; X86-LABEL: btr_32_dont_fold:768; X86: # %bb.0:769; X86-NEXT: movl {{[0-9]+}}(%esp), %eax770; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx771; X86-NEXT: movl $-2, %edx772; X86-NEXT: roll %cl, %edx773; X86-NEXT: andl %edx, (%eax)774; X86-NEXT: retl775 %1 = load i32, ptr %x776 %2 = shl i32 1, %n777 %3 = xor i32 %2, -1778 %4 = and i32 %1, %3779 store i32 %4, ptr %x780 ret void781}782 783define void @bts_32_dont_fold(ptr %x, i32 %n) {784; X64-LABEL: bts_32_dont_fold:785; X64: # %bb.0:786; X64-NEXT: movl %esi, %ecx787; X64-NEXT: movl $1, %eax788; X64-NEXT: # kill: def $cl killed $cl killed $ecx789; X64-NEXT: shll %cl, %eax790; X64-NEXT: orl %eax, (%rdi)791; X64-NEXT: retq792;793; X86-LABEL: bts_32_dont_fold:794; X86: # %bb.0:795; X86-NEXT: movl {{[0-9]+}}(%esp), %eax796; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx797; X86-NEXT: movl $1, %edx798; X86-NEXT: shll %cl, %edx799; X86-NEXT: orl %edx, (%eax)800; X86-NEXT: retl801 %1 = load i32, ptr %x802 %2 = shl i32 1, %n803 %3 = or i32 %1, %2804 store i32 %3, ptr %x805 ret void806}807 808define void @btc_32_dont_fold(ptr %x, i32 %n) {809; X64-LABEL: btc_32_dont_fold:810; X64: # %bb.0:811; X64-NEXT: movl %esi, %ecx812; X64-NEXT: movl $1, %eax813; X64-NEXT: # kill: def $cl killed $cl killed $ecx814; X64-NEXT: shll %cl, %eax815; X64-NEXT: xorl %eax, (%rdi)816; X64-NEXT: retq817;818; X86-LABEL: btc_32_dont_fold:819; X86: # %bb.0:820; X86-NEXT: movl {{[0-9]+}}(%esp), %eax821; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx822; X86-NEXT: movl $1, %edx823; X86-NEXT: shll %cl, %edx824; X86-NEXT: xorl %edx, (%eax)825; X86-NEXT: retl826 %1 = load i32, ptr %x827 %2 = shl i32 1, %n828 %3 = xor i32 %1, %2829 store i32 %3, ptr %x830 ret void831}832 833define void @btr_64_dont_fold(ptr %x, i64 %n) {834; X64-LABEL: btr_64_dont_fold:835; X64: # %bb.0:836; X64-NEXT: movq %rsi, %rcx837; X64-NEXT: movq $-2, %rax838; X64-NEXT: # kill: def $cl killed $cl killed $rcx839; X64-NEXT: rolq %cl, %rax840; X64-NEXT: andq %rax, (%rdi)841; X64-NEXT: retq842;843; X86-LABEL: btr_64_dont_fold:844; X86: # %bb.0:845; X86-NEXT: pushl %esi846; X86-NEXT: .cfi_def_cfa_offset 8847; X86-NEXT: .cfi_offset %esi, -8848; X86-NEXT: movl {{[0-9]+}}(%esp), %eax849; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx850; X86-NEXT: movl $1, %edx851; X86-NEXT: xorl %esi, %esi852; X86-NEXT: shldl %cl, %edx, %esi853; X86-NEXT: shll %cl, %edx854; X86-NEXT: testb $32, %cl855; X86-NEXT: je .LBB33_2856; X86-NEXT: # %bb.1:857; X86-NEXT: movl %edx, %esi858; X86-NEXT: xorl %edx, %edx859; X86-NEXT: .LBB33_2:860; X86-NEXT: notl %esi861; X86-NEXT: notl %edx862; X86-NEXT: andl %edx, (%eax)863; X86-NEXT: andl %esi, 4(%eax)864; X86-NEXT: popl %esi865; X86-NEXT: .cfi_def_cfa_offset 4866; X86-NEXT: retl867 %1 = load i64, ptr %x868 %2 = shl i64 1, %n869 %3 = xor i64 %2, -1870 %4 = and i64 %1, %3871 store i64 %4, ptr %x872 ret void873}874 875define void @bts_64_dont_fold(ptr %x, i64 %n) {876; X64-LABEL: bts_64_dont_fold:877; X64: # %bb.0:878; X64-NEXT: movq %rsi, %rcx879; X64-NEXT: movl $1, %eax880; X64-NEXT: # kill: def $cl killed $cl killed $rcx881; X64-NEXT: shlq %cl, %rax882; X64-NEXT: orq %rax, (%rdi)883; X64-NEXT: retq884;885; X86-LABEL: bts_64_dont_fold:886; X86: # %bb.0:887; X86-NEXT: pushl %esi888; X86-NEXT: .cfi_def_cfa_offset 8889; X86-NEXT: .cfi_offset %esi, -8890; X86-NEXT: movl {{[0-9]+}}(%esp), %eax891; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx892; X86-NEXT: movl $1, %edx893; X86-NEXT: xorl %esi, %esi894; X86-NEXT: shldl %cl, %edx, %esi895; X86-NEXT: shll %cl, %edx896; X86-NEXT: testb $32, %cl897; X86-NEXT: je .LBB34_2898; X86-NEXT: # %bb.1:899; X86-NEXT: movl %edx, %esi900; X86-NEXT: xorl %edx, %edx901; X86-NEXT: .LBB34_2:902; X86-NEXT: orl %edx, (%eax)903; X86-NEXT: orl %esi, 4(%eax)904; X86-NEXT: popl %esi905; X86-NEXT: .cfi_def_cfa_offset 4906; X86-NEXT: retl907 %1 = load i64, ptr %x908 %2 = shl i64 1, %n909 %3 = or i64 %1, %2910 store i64 %3, ptr %x911 ret void912}913 914define void @btc_64_dont_fold(ptr %x, i64 %n) {915; X64-LABEL: btc_64_dont_fold:916; X64: # %bb.0:917; X64-NEXT: movq %rsi, %rcx918; X64-NEXT: movl $1, %eax919; X64-NEXT: # kill: def $cl killed $cl killed $rcx920; X64-NEXT: shlq %cl, %rax921; X64-NEXT: xorq %rax, (%rdi)922; X64-NEXT: retq923;924; X86-LABEL: btc_64_dont_fold:925; X86: # %bb.0:926; X86-NEXT: pushl %esi927; X86-NEXT: .cfi_def_cfa_offset 8928; X86-NEXT: .cfi_offset %esi, -8929; X86-NEXT: movl {{[0-9]+}}(%esp), %eax930; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx931; X86-NEXT: movl $1, %edx932; X86-NEXT: xorl %esi, %esi933; X86-NEXT: shldl %cl, %edx, %esi934; X86-NEXT: shll %cl, %edx935; X86-NEXT: testb $32, %cl936; X86-NEXT: je .LBB35_2937; X86-NEXT: # %bb.1:938; X86-NEXT: movl %edx, %esi939; X86-NEXT: xorl %edx, %edx940; X86-NEXT: .LBB35_2:941; X86-NEXT: xorl %edx, (%eax)942; X86-NEXT: xorl %esi, 4(%eax)943; X86-NEXT: popl %esi944; X86-NEXT: .cfi_def_cfa_offset 4945; X86-NEXT: retl946 %1 = load i64, ptr %x947 %2 = shl i64 1, %n948 %3 = xor i64 %1, %2949 store i64 %3, ptr %x950 ret void951}952 953define i32 @btr_32_mask_zeros(i32 %x, i32 %n) {954; X64-LABEL: btr_32_mask_zeros:955; X64: # %bb.0:956; X64-NEXT: movl %edi, %eax957; X64-NEXT: shll $2, %esi958; X64-NEXT: btrl %esi, %eax959; X64-NEXT: retq960;961; X86-LABEL: btr_32_mask_zeros:962; X86: # %bb.0:963; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx964; X86-NEXT: shlb $2, %cl965; X86-NEXT: movl {{[0-9]+}}(%esp), %eax966; X86-NEXT: btrl %ecx, %eax967; X86-NEXT: retl968 %1 = shl i32 %n, 2969 %2 = and i32 %1, 31970 %3 = shl i32 1, %2971 %4 = xor i32 %3, -1972 %5 = and i32 %x, %4973 ret i32 %5974}975 976define i32 @bts_32_mask_zeros(i32 %x, i32 %n) {977; X64-LABEL: bts_32_mask_zeros:978; X64: # %bb.0:979; X64-NEXT: movl %edi, %eax980; X64-NEXT: shll $2, %esi981; X64-NEXT: btsl %esi, %eax982; X64-NEXT: retq983;984; X86-LABEL: bts_32_mask_zeros:985; X86: # %bb.0:986; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx987; X86-NEXT: shlb $2, %cl988; X86-NEXT: movl {{[0-9]+}}(%esp), %eax989; X86-NEXT: btsl %ecx, %eax990; X86-NEXT: retl991 %1 = shl i32 %n, 2992 %2 = and i32 %1, 31993 %3 = shl i32 1, %2994 %4 = or i32 %x, %3995 ret i32 %4996}997 998define i32 @btc_32_mask_zeros(i32 %x, i32 %n) {999; X64-LABEL: btc_32_mask_zeros:1000; X64: # %bb.0:1001; X64-NEXT: movl %edi, %eax1002; X64-NEXT: shll $2, %esi1003; X64-NEXT: btcl %esi, %eax1004; X64-NEXT: retq1005;1006; X86-LABEL: btc_32_mask_zeros:1007; X86: # %bb.0:1008; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx1009; X86-NEXT: shlb $2, %cl1010; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1011; X86-NEXT: btcl %ecx, %eax1012; X86-NEXT: retl1013 %1 = shl i32 %n, 21014 %2 = and i32 %1, 311015 %3 = shl i32 1, %21016 %4 = xor i32 %x, %31017 ret i32 %41018}1019 1020define i64 @btr_64_mask_zeros(i64 %x, i64 %n) {1021; X64-LABEL: btr_64_mask_zeros:1022; X64: # %bb.0:1023; X64-NEXT: movq %rdi, %rax1024; X64-NEXT: shll $2, %esi1025; X64-NEXT: btrq %rsi, %rax1026; X64-NEXT: retq1027;1028; X86-LABEL: btr_64_mask_zeros:1029; X86: # %bb.0:1030; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1031; X86-NEXT: shll $2, %ecx1032; X86-NEXT: movl $1, %eax1033; X86-NEXT: xorl %edx, %edx1034; X86-NEXT: shldl %cl, %eax, %edx1035; X86-NEXT: shll %cl, %eax1036; X86-NEXT: testb $32, %cl1037; X86-NEXT: je .LBB39_21038; X86-NEXT: # %bb.1:1039; X86-NEXT: movl %eax, %edx1040; X86-NEXT: xorl %eax, %eax1041; X86-NEXT: .LBB39_2:1042; X86-NEXT: notl %edx1043; X86-NEXT: notl %eax1044; X86-NEXT: andl {{[0-9]+}}(%esp), %edx1045; X86-NEXT: andl {{[0-9]+}}(%esp), %eax1046; X86-NEXT: retl1047 %1 = shl i64 %n, 21048 %2 = and i64 %1, 631049 %3 = shl i64 1, %21050 %4 = xor i64 %3, -11051 %5 = and i64 %x, %41052 ret i64 %51053}1054 1055define i64 @bts_64_mask_zeros(i64 %x, i64 %n) {1056; X64-LABEL: bts_64_mask_zeros:1057; X64: # %bb.0:1058; X64-NEXT: movq %rdi, %rax1059; X64-NEXT: shll $2, %esi1060; X64-NEXT: btsq %rsi, %rax1061; X64-NEXT: retq1062;1063; X86-LABEL: bts_64_mask_zeros:1064; X86: # %bb.0:1065; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1066; X86-NEXT: shll $2, %ecx1067; X86-NEXT: movl $1, %eax1068; X86-NEXT: xorl %edx, %edx1069; X86-NEXT: shldl %cl, %eax, %edx1070; X86-NEXT: shll %cl, %eax1071; X86-NEXT: testb $32, %cl1072; X86-NEXT: je .LBB40_21073; X86-NEXT: # %bb.1:1074; X86-NEXT: movl %eax, %edx1075; X86-NEXT: xorl %eax, %eax1076; X86-NEXT: .LBB40_2:1077; X86-NEXT: orl {{[0-9]+}}(%esp), %edx1078; X86-NEXT: orl {{[0-9]+}}(%esp), %eax1079; X86-NEXT: retl1080 %1 = shl i64 %n, 21081 %2 = and i64 %1, 631082 %3 = shl i64 1, %21083 %4 = or i64 %x, %31084 ret i64 %41085}1086 1087define i64 @btc_64_mask_zeros(i64 %x, i64 %n) {1088; X64-LABEL: btc_64_mask_zeros:1089; X64: # %bb.0:1090; X64-NEXT: movq %rdi, %rax1091; X64-NEXT: shll $2, %esi1092; X64-NEXT: btcq %rsi, %rax1093; X64-NEXT: retq1094;1095; X86-LABEL: btc_64_mask_zeros:1096; X86: # %bb.0:1097; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx1098; X86-NEXT: shll $2, %ecx1099; X86-NEXT: movl $1, %eax1100; X86-NEXT: xorl %edx, %edx1101; X86-NEXT: shldl %cl, %eax, %edx1102; X86-NEXT: shll %cl, %eax1103; X86-NEXT: testb $32, %cl1104; X86-NEXT: je .LBB41_21105; X86-NEXT: # %bb.1:1106; X86-NEXT: movl %eax, %edx1107; X86-NEXT: xorl %eax, %eax1108; X86-NEXT: .LBB41_2:1109; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx1110; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax1111; X86-NEXT: retl1112 %1 = shl i64 %n, 21113 %2 = and i64 %1, 631114 %3 = shl i64 1, %21115 %4 = xor i64 %x, %31116 ret i64 %41117}1118