597 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@v16 = dso_local global i16 0, align 26@v32 = dso_local global i32 0, align 47@v64 = dso_local global i64 0, align 88 9define i16 @bts1() nounwind {10; X86-LABEL: bts1:11; X86: # %bb.0: # %entry12; X86-NEXT: xorl %eax, %eax13; X86-NEXT: lock btsw $0, v1614; X86-NEXT: setb %al15; X86-NEXT: # kill: def $ax killed $ax killed $eax16; X86-NEXT: retl17;18; X64-LABEL: bts1:19; X64: # %bb.0: # %entry20; X64-NEXT: xorl %eax, %eax21; X64-NEXT: lock btsw $0, v16(%rip)22; X64-NEXT: setb %al23; X64-NEXT: # kill: def $ax killed $ax killed $eax24; X64-NEXT: retq25entry:26 %0 = atomicrmw or ptr @v16, i16 1 monotonic, align 227 %and = and i16 %0, 128 ret i16 %and29}30 31define i16 @bts2() nounwind {32; X86-LABEL: bts2:33; X86: # %bb.0: # %entry34; X86-NEXT: xorl %eax, %eax35; X86-NEXT: lock btsw $1, v1636; X86-NEXT: setb %al37; X86-NEXT: addl %eax, %eax38; X86-NEXT: # kill: def $ax killed $ax killed $eax39; X86-NEXT: retl40;41; X64-LABEL: bts2:42; X64: # %bb.0: # %entry43; X64-NEXT: xorl %eax, %eax44; X64-NEXT: lock btsw $1, v16(%rip)45; X64-NEXT: setb %al46; X64-NEXT: addl %eax, %eax47; X64-NEXT: # kill: def $ax killed $ax killed $eax48; X64-NEXT: retq49entry:50 %0 = atomicrmw or ptr @v16, i16 2 monotonic, align 251 %and = and i16 %0, 252 ret i16 %and53}54 55define i16 @bts15() nounwind {56; X86-LABEL: bts15:57; X86: # %bb.0: # %entry58; X86-NEXT: xorl %eax, %eax59; X86-NEXT: lock btsw $15, v1660; X86-NEXT: setb %al61; X86-NEXT: shll $15, %eax62; X86-NEXT: # kill: def $ax killed $ax killed $eax63; X86-NEXT: retl64;65; X64-LABEL: bts15:66; X64: # %bb.0: # %entry67; X64-NEXT: xorl %eax, %eax68; X64-NEXT: lock btsw $15, v16(%rip)69; X64-NEXT: setb %al70; X64-NEXT: shll $15, %eax71; X64-NEXT: # kill: def $ax killed $ax killed $eax72; X64-NEXT: retq73entry:74 %0 = atomicrmw or ptr @v16, i16 32768 monotonic, align 275 %and = and i16 %0, 3276876 ret i16 %and77}78 79define i32 @bts31() nounwind {80; X86-LABEL: bts31:81; X86: # %bb.0: # %entry82; X86-NEXT: xorl %eax, %eax83; X86-NEXT: lock btsl $31, v3284; X86-NEXT: setb %al85; X86-NEXT: shll $31, %eax86; X86-NEXT: retl87;88; X64-LABEL: bts31:89; X64: # %bb.0: # %entry90; X64-NEXT: xorl %eax, %eax91; X64-NEXT: lock btsl $31, v32(%rip)92; X64-NEXT: setb %al93; X64-NEXT: shll $31, %eax94; X64-NEXT: retq95entry:96 %0 = atomicrmw or ptr @v32, i32 2147483648 monotonic, align 497 %and = and i32 %0, 214748364898 ret i32 %and99}100 101define i64 @bts63() nounwind {102; X86-LABEL: bts63:103; X86: # %bb.0: # %entry104; X86-NEXT: pushl %ebx105; X86-NEXT: pushl %esi106; X86-NEXT: movl $-2147483648, %esi # imm = 0x80000000107; X86-NEXT: movl v64+4, %edx108; X86-NEXT: movl v64, %eax109; X86-NEXT: .p2align 4110; X86-NEXT: .LBB4_1: # %atomicrmw.start111; X86-NEXT: # =>This Inner Loop Header: Depth=1112; X86-NEXT: movl %edx, %ecx113; X86-NEXT: orl %esi, %ecx114; X86-NEXT: movl %eax, %ebx115; X86-NEXT: lock cmpxchg8b v64116; X86-NEXT: jne .LBB4_1117; X86-NEXT: # %bb.2: # %atomicrmw.end118; X86-NEXT: andl %esi, %edx119; X86-NEXT: xorl %eax, %eax120; X86-NEXT: popl %esi121; X86-NEXT: popl %ebx122; X86-NEXT: retl123;124; X64-LABEL: bts63:125; X64: # %bb.0: # %entry126; X64-NEXT: xorl %eax, %eax127; X64-NEXT: lock btsq $63, v64(%rip)128; X64-NEXT: setb %al129; X64-NEXT: shlq $63, %rax130; X64-NEXT: retq131entry:132 %0 = atomicrmw or ptr @v64, i64 -9223372036854775808 monotonic, align 8133 %and = and i64 %0, -9223372036854775808134 ret i64 %and135}136 137define i16 @btc1() nounwind {138; X86-LABEL: btc1:139; X86: # %bb.0: # %entry140; X86-NEXT: xorl %eax, %eax141; X86-NEXT: lock btcw $0, v16142; X86-NEXT: setb %al143; X86-NEXT: # kill: def $ax killed $ax killed $eax144; X86-NEXT: retl145;146; X64-LABEL: btc1:147; X64: # %bb.0: # %entry148; X64-NEXT: xorl %eax, %eax149; X64-NEXT: lock btcw $0, v16(%rip)150; X64-NEXT: setb %al151; X64-NEXT: # kill: def $ax killed $ax killed $eax152; X64-NEXT: retq153entry:154 %0 = atomicrmw xor ptr @v16, i16 1 monotonic, align 2155 %and = and i16 %0, 1156 ret i16 %and157}158 159define i16 @btc2() nounwind {160; X86-LABEL: btc2:161; X86: # %bb.0: # %entry162; X86-NEXT: xorl %eax, %eax163; X86-NEXT: lock btcw $1, v16164; X86-NEXT: setb %al165; X86-NEXT: addl %eax, %eax166; X86-NEXT: # kill: def $ax killed $ax killed $eax167; X86-NEXT: retl168;169; X64-LABEL: btc2:170; X64: # %bb.0: # %entry171; X64-NEXT: xorl %eax, %eax172; X64-NEXT: lock btcw $1, v16(%rip)173; X64-NEXT: setb %al174; X64-NEXT: addl %eax, %eax175; X64-NEXT: # kill: def $ax killed $ax killed $eax176; X64-NEXT: retq177entry:178 %0 = atomicrmw xor ptr @v16, i16 2 monotonic, align 2179 %and = and i16 %0, 2180 ret i16 %and181}182 183define i16 @btc15() nounwind {184; X86-LABEL: btc15:185; X86: # %bb.0: # %entry186; X86-NEXT: movw $-32768, %ax # imm = 0x8000187; X86-NEXT: lock xaddw %ax, v16188; X86-NEXT: andl $32768, %eax # imm = 0x8000189; X86-NEXT: # kill: def $ax killed $ax killed $eax190; X86-NEXT: retl191;192; X64-LABEL: btc15:193; X64: # %bb.0: # %entry194; X64-NEXT: movw $-32768, %ax # imm = 0x8000195; X64-NEXT: lock xaddw %ax, v16(%rip)196; X64-NEXT: andl $32768, %eax # imm = 0x8000197; X64-NEXT: # kill: def $ax killed $ax killed $eax198; X64-NEXT: retq199entry:200 %0 = atomicrmw xor ptr @v16, i16 32768 monotonic, align 2201 %and = and i16 %0, 32768202 ret i16 %and203}204 205define i32 @btc31() nounwind {206; X86-LABEL: btc31:207; X86: # %bb.0: # %entry208; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000209; X86-NEXT: lock xaddl %eax, v32210; X86-NEXT: andl $-2147483648, %eax # imm = 0x80000000211; X86-NEXT: retl212;213; X64-LABEL: btc31:214; X64: # %bb.0: # %entry215; X64-NEXT: movl $-2147483648, %eax # imm = 0x80000000216; X64-NEXT: lock xaddl %eax, v32(%rip)217; X64-NEXT: andl $-2147483648, %eax # imm = 0x80000000218; X64-NEXT: retq219entry:220 %0 = atomicrmw xor ptr @v32, i32 2147483648 monotonic, align 4221 %and = and i32 %0, 2147483648222 ret i32 %and223}224 225define i64 @btc63() nounwind {226; X86-LABEL: btc63:227; X86: # %bb.0: # %entry228; X86-NEXT: pushl %ebx229; X86-NEXT: pushl %esi230; X86-NEXT: movl $-2147483648, %esi # imm = 0x80000000231; X86-NEXT: movl v64+4, %edx232; X86-NEXT: movl v64, %eax233; X86-NEXT: .p2align 4234; X86-NEXT: .LBB9_1: # %atomicrmw.start235; X86-NEXT: # =>This Inner Loop Header: Depth=1236; X86-NEXT: movl %edx, %ecx237; X86-NEXT: xorl %esi, %ecx238; X86-NEXT: movl %eax, %ebx239; X86-NEXT: lock cmpxchg8b v64240; X86-NEXT: jne .LBB9_1241; X86-NEXT: # %bb.2: # %atomicrmw.end242; X86-NEXT: andl %esi, %edx243; X86-NEXT: xorl %eax, %eax244; X86-NEXT: popl %esi245; X86-NEXT: popl %ebx246; X86-NEXT: retl247;248; X64-LABEL: btc63:249; X64: # %bb.0: # %entry250; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000251; X64-NEXT: movq %rcx, %rax252; X64-NEXT: lock xaddq %rax, v64(%rip)253; X64-NEXT: andq %rcx, %rax254; X64-NEXT: retq255entry:256 %0 = atomicrmw xor ptr @v64, i64 -9223372036854775808 monotonic, align 8257 %and = and i64 %0, -9223372036854775808258 ret i64 %and259}260 261define i16 @btr1() nounwind {262; X86-LABEL: btr1:263; X86: # %bb.0: # %entry264; X86-NEXT: xorl %eax, %eax265; X86-NEXT: lock btrw $0, v16266; X86-NEXT: setb %al267; X86-NEXT: # kill: def $ax killed $ax killed $eax268; X86-NEXT: retl269;270; X64-LABEL: btr1:271; X64: # %bb.0: # %entry272; X64-NEXT: xorl %eax, %eax273; X64-NEXT: lock btrw $0, v16(%rip)274; X64-NEXT: setb %al275; X64-NEXT: # kill: def $ax killed $ax killed $eax276; X64-NEXT: retq277entry:278 %0 = atomicrmw and ptr @v16, i16 -2 monotonic, align 2279 %and = and i16 %0, 1280 ret i16 %and281}282 283define i16 @btr2() nounwind {284; X86-LABEL: btr2:285; X86: # %bb.0: # %entry286; X86-NEXT: xorl %eax, %eax287; X86-NEXT: lock btrw $1, v16288; X86-NEXT: setb %al289; X86-NEXT: addl %eax, %eax290; X86-NEXT: # kill: def $ax killed $ax killed $eax291; X86-NEXT: retl292;293; X64-LABEL: btr2:294; X64: # %bb.0: # %entry295; X64-NEXT: xorl %eax, %eax296; X64-NEXT: lock btrw $1, v16(%rip)297; X64-NEXT: setb %al298; X64-NEXT: addl %eax, %eax299; X64-NEXT: # kill: def $ax killed $ax killed $eax300; X64-NEXT: retq301entry:302 %0 = atomicrmw and ptr @v16, i16 -3 monotonic, align 2303 %and = and i16 %0, 2304 ret i16 %and305}306 307define i16 @btr15() nounwind {308; X86-LABEL: btr15:309; X86: # %bb.0: # %entry310; X86-NEXT: xorl %eax, %eax311; X86-NEXT: lock btrw $15, v16312; X86-NEXT: setb %al313; X86-NEXT: shll $15, %eax314; X86-NEXT: # kill: def $ax killed $ax killed $eax315; X86-NEXT: retl316;317; X64-LABEL: btr15:318; X64: # %bb.0: # %entry319; X64-NEXT: xorl %eax, %eax320; X64-NEXT: lock btrw $15, v16(%rip)321; X64-NEXT: setb %al322; X64-NEXT: shll $15, %eax323; X64-NEXT: # kill: def $ax killed $ax killed $eax324; X64-NEXT: retq325entry:326 %0 = atomicrmw and ptr @v16, i16 32767 monotonic, align 2327 %and = and i16 %0, 32768328 ret i16 %and329}330 331define i32 @btr31() nounwind {332; X86-LABEL: btr31:333; X86: # %bb.0: # %entry334; X86-NEXT: xorl %eax, %eax335; X86-NEXT: lock btrl $31, v32336; X86-NEXT: setb %al337; X86-NEXT: shll $31, %eax338; X86-NEXT: retl339;340; X64-LABEL: btr31:341; X64: # %bb.0: # %entry342; X64-NEXT: xorl %eax, %eax343; X64-NEXT: lock btrl $31, v32(%rip)344; X64-NEXT: setb %al345; X64-NEXT: shll $31, %eax346; X64-NEXT: retq347entry:348 %0 = atomicrmw and ptr @v32, i32 2147483647 monotonic, align 4349 %and = and i32 %0, 2147483648350 ret i32 %and351}352 353define i64 @btr63() nounwind {354; X86-LABEL: btr63:355; X86: # %bb.0: # %entry356; X86-NEXT: pushl %ebx357; X86-NEXT: pushl %edi358; X86-NEXT: pushl %esi359; X86-NEXT: movl $2147483647, %esi # imm = 0x7FFFFFFF360; X86-NEXT: movl $-1, %edi361; X86-NEXT: movl v64+4, %edx362; X86-NEXT: movl v64, %eax363; X86-NEXT: .p2align 4364; X86-NEXT: .LBB14_1: # %atomicrmw.start365; X86-NEXT: # =>This Inner Loop Header: Depth=1366; X86-NEXT: movl %eax, %ebx367; X86-NEXT: andl %edi, %ebx368; X86-NEXT: movl %edx, %ecx369; X86-NEXT: andl %esi, %ecx370; X86-NEXT: lock cmpxchg8b v64371; X86-NEXT: jne .LBB14_1372; X86-NEXT: # %bb.2: # %atomicrmw.end373; X86-NEXT: addl $1, %edi374; X86-NEXT: adcl $0, %esi375; X86-NEXT: andl %edi, %eax376; X86-NEXT: andl %esi, %edx377; X86-NEXT: popl %esi378; X86-NEXT: popl %edi379; X86-NEXT: popl %ebx380; X86-NEXT: retl381;382; X64-LABEL: btr63:383; X64: # %bb.0: # %entry384; X64-NEXT: xorl %eax, %eax385; X64-NEXT: lock btrq $63, v64(%rip)386; X64-NEXT: setb %al387; X64-NEXT: shlq $63, %rax388; X64-NEXT: retq389entry:390 %0 = atomicrmw and ptr @v64, i64 9223372036854775807 monotonic, align 8391 %and = and i64 %0, -9223372036854775808392 ret i64 %and393}394 395define i16 @multi_use1() nounwind {396; X86-LABEL: multi_use1:397; X86: # %bb.0: # %entry398; X86-NEXT: movzwl v16, %eax399; X86-NEXT: .p2align 4400; X86-NEXT: .LBB15_1: # %atomicrmw.start401; X86-NEXT: # =>This Inner Loop Header: Depth=1402; X86-NEXT: movl %eax, %ecx403; X86-NEXT: orl $1, %ecx404; X86-NEXT: # kill: def $ax killed $ax killed $eax405; X86-NEXT: lock cmpxchgw %cx, v16406; X86-NEXT: # kill: def $ax killed $ax def $eax407; X86-NEXT: jne .LBB15_1408; X86-NEXT: # %bb.2: # %atomicrmw.end409; X86-NEXT: movl %eax, %ecx410; X86-NEXT: andl $1, %ecx411; X86-NEXT: xorl $2, %eax412; X86-NEXT: orl %ecx, %eax413; X86-NEXT: # kill: def $ax killed $ax killed $eax414; X86-NEXT: retl415;416; X64-LABEL: multi_use1:417; X64: # %bb.0: # %entry418; X64-NEXT: movzwl v16(%rip), %eax419; X64-NEXT: .p2align 4420; X64-NEXT: .LBB15_1: # %atomicrmw.start421; X64-NEXT: # =>This Inner Loop Header: Depth=1422; X64-NEXT: movl %eax, %ecx423; X64-NEXT: orl $1, %ecx424; X64-NEXT: # kill: def $ax killed $ax killed $eax425; X64-NEXT: lock cmpxchgw %cx, v16(%rip)426; X64-NEXT: # kill: def $ax killed $ax def $eax427; X64-NEXT: jne .LBB15_1428; X64-NEXT: # %bb.2: # %atomicrmw.end429; X64-NEXT: movl %eax, %ecx430; X64-NEXT: andl $1, %ecx431; X64-NEXT: xorl $2, %eax432; X64-NEXT: orl %ecx, %eax433; X64-NEXT: # kill: def $ax killed $ax killed $eax434; X64-NEXT: retq435entry:436 %0 = atomicrmw or ptr @v16, i16 1 monotonic, align 2437 %1 = and i16 %0, 1438 %2 = xor i16 %0, 2439 %3 = or i16 %1, %2440 ret i16 %3441}442 443define i16 @multi_use2() nounwind {444; X86-LABEL: multi_use2:445; X86: # %bb.0: # %entry446; X86-NEXT: xorl %eax, %eax447; X86-NEXT: lock btsw $0, v16448; X86-NEXT: setb %al449; X86-NEXT: leal (%eax,%eax,2), %eax450; X86-NEXT: # kill: def $ax killed $ax killed $eax451; X86-NEXT: retl452;453; X64-LABEL: multi_use2:454; X64: # %bb.0: # %entry455; X64-NEXT: xorl %eax, %eax456; X64-NEXT: lock btsw $0, v16(%rip)457; X64-NEXT: setb %al458; X64-NEXT: leal (%rax,%rax,2), %eax459; X64-NEXT: # kill: def $ax killed $ax killed $eax460; X64-NEXT: retq461entry:462 %0 = atomicrmw or ptr @v16, i16 1 monotonic, align 2463 %1 = and i16 %0, 1464 %2 = shl i16 %1, 1465 %3 = or i16 %1, %2466 ret i16 %3467}468 469define i16 @use_in_diff_bb() nounwind {470; X86-LABEL: use_in_diff_bb:471; X86: # %bb.0: # %entry472; X86-NEXT: movzwl v16, %eax473; X86-NEXT: .p2align 4474; X86-NEXT: .LBB17_1: # %atomicrmw.start475; X86-NEXT: # =>This Inner Loop Header: Depth=1476; X86-NEXT: movl %eax, %ecx477; X86-NEXT: orl $1, %ecx478; X86-NEXT: # kill: def $ax killed $ax killed $eax479; X86-NEXT: lock cmpxchgw %cx, v16480; X86-NEXT: # kill: def $ax killed $ax def $eax481; X86-NEXT: jne .LBB17_1482; X86-NEXT: # %bb.2: # %atomicrmw.end483; X86-NEXT: xorl %ecx, %ecx484; X86-NEXT: testb %cl, %cl485; X86-NEXT: jne .LBB17_4486; X86-NEXT: # %bb.3:487; X86-NEXT: pushl %esi488; X86-NEXT: movl %eax, %esi489; X86-NEXT: calll foo@PLT490; X86-NEXT: movl %esi, %eax491; X86-NEXT: popl %esi492; X86-NEXT: .LBB17_4:493; X86-NEXT: andl $1, %eax494; X86-NEXT: # kill: def $ax killed $ax killed $eax495; X86-NEXT: retl496;497; X64-LABEL: use_in_diff_bb:498; X64: # %bb.0: # %entry499; X64-NEXT: movzwl v16(%rip), %eax500; X64-NEXT: .p2align 4501; X64-NEXT: .LBB17_1: # %atomicrmw.start502; X64-NEXT: # =>This Inner Loop Header: Depth=1503; X64-NEXT: movl %eax, %ecx504; X64-NEXT: orl $1, %ecx505; X64-NEXT: # kill: def $ax killed $ax killed $eax506; X64-NEXT: lock cmpxchgw %cx, v16(%rip)507; X64-NEXT: # kill: def $ax killed $ax def $eax508; X64-NEXT: jne .LBB17_1509; X64-NEXT: # %bb.2: # %atomicrmw.end510; X64-NEXT: xorl %ecx, %ecx511; X64-NEXT: testb %cl, %cl512; X64-NEXT: jne .LBB17_4513; X64-NEXT: # %bb.3:514; X64-NEXT: pushq %rbx515; X64-NEXT: movl %eax, %ebx516; X64-NEXT: callq foo@PLT517; X64-NEXT: movl %ebx, %eax518; X64-NEXT: popq %rbx519; X64-NEXT: .LBB17_4:520; X64-NEXT: andl $1, %eax521; X64-NEXT: # kill: def $ax killed $ax killed $eax522; X64-NEXT: retq523entry:524 %0 = atomicrmw or ptr @v16, i16 1 monotonic, align 2525 br i1 undef, label %1, label %25261:527 call void @foo()528 br label %35292:530 br label %35313:532 %and = and i16 %0, 1533 ret i16 %and534}535 536declare void @foo()537 538define void @no_and_cmp0_fold() nounwind {539; X86-LABEL: no_and_cmp0_fold:540; X86: # %bb.0: # %entry541; X86-NEXT: lock btsl $3, v32542; X86-NEXT: xorl %eax, %eax543; X86-NEXT: testb %al, %al544; X86-NEXT: je .LBB18_1545; X86-NEXT: # %bb.2: # %if.end546; X86-NEXT: retl547; X86-NEXT: .LBB18_1: # %if.then548;549; X64-LABEL: no_and_cmp0_fold:550; X64: # %bb.0: # %entry551; X64-NEXT: lock btsl $3, v32(%rip)552; X64-NEXT: xorl %eax, %eax553; X64-NEXT: testb %al, %al554; X64-NEXT: je .LBB18_1555; X64-NEXT: # %bb.2: # %if.end556; X64-NEXT: retq557; X64-NEXT: .LBB18_1: # %if.then558entry:559 %0 = atomicrmw or ptr @v32, i32 8 monotonic, align 4560 %and = and i32 %0, 8561 %tobool = icmp ne i32 %and, 0562 br i1 undef, label %if.then, label %if.end563 564if.then: ; preds = %entry565 unreachable566 567if.end: ; preds = %entry568 %or.cond8 = select i1 %tobool, i1 undef, i1 false569 ret void570}571 572define i32 @split_hoist_and(i32 %0) nounwind {573; X86-LABEL: split_hoist_and:574; X86: # %bb.0:575; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx576; X86-NEXT: xorl %eax, %eax577; X86-NEXT: lock btsl $3, v32578; X86-NEXT: setb %al579; X86-NEXT: shll $3, %eax580; X86-NEXT: testl %ecx, %ecx581; X86-NEXT: retl582;583; X64-LABEL: split_hoist_and:584; X64: # %bb.0:585; X64-NEXT: xorl %eax, %eax586; X64-NEXT: lock btsl $3, v32(%rip)587; X64-NEXT: setb %al588; X64-NEXT: shll $3, %eax589; X64-NEXT: retq590 %2 = atomicrmw or ptr @v32, i32 8 monotonic, align 4591 %3 = tail call i32 @llvm.ctlz.i32(i32 %0, i1 false)592 %4 = and i32 %2, 8593 ret i32 %4594}595 596declare i32 @llvm.ctlz.i32(i32, i1)597