brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.5 KiB · 0d0108f Raw
1759 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefix X64 --check-prefix FAST_INC3; RUN: llc < %s -mtriple=i686-unknown-unknown -verify-machineinstrs | FileCheck %s --check-prefix X324; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=slow-incdec -verify-machineinstrs | FileCheck %s --check-prefix X64 --check-prefix SLOW_INC5 6; This file checks that atomic (non-seq_cst) stores of immediate values are7; done in one mov instruction and not 2. More precisely, it makes sure that the8; immediate is not first copied uselessly into a register.9 10; Similarily, it checks that a binary operation of an immediate with an atomic11; variable that is stored back in that variable is done as a single instruction.12; For example: x.store(42 + x.load(memory_order_acquire), memory_order_release)13; should be just an add instruction, instead of loading x into a register, doing14; an add and storing the result back.15; The binary operations supported are currently add, and, or, xor.16; sub is not supported because they are translated by an addition of the17; negated immediate.18;19; We also check the same patterns:20; - For inc/dec.21; - For register instead of immediate operands.22; - For floating point operations.23 24; seq_cst stores are left as (lock) xchgl, but we try to check every other25; attribute at least once.26 27; Please note that these operations do not require the lock prefix: only28; sequentially consistent stores require this kind of protection on X86.29; And even for seq_cst operations, llvm uses the xchg instruction which has30; an implicit lock prefix, so making it explicit is not required.31 32define void @store_atomic_imm_8(ptr %p) {33; X64-LABEL: store_atomic_imm_8:34; X64:       # %bb.0:35; X64-NEXT:    movb $42, (%rdi)36; X64-NEXT:    retq37;38; X32-LABEL: store_atomic_imm_8:39; X32:       # %bb.0:40; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax41; X32-NEXT:    movb $42, (%eax)42; X32-NEXT:    retl43  store atomic i8 42, ptr %p release, align 144  ret void45}46 47define void @store_atomic_imm_16(ptr %p) {48; X64-LABEL: store_atomic_imm_16:49; X64:       # %bb.0:50; X64-NEXT:    movw $42, (%rdi)51; X64-NEXT:    retq52;53; X32-LABEL: store_atomic_imm_16:54; X32:       # %bb.0:55; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax56; X32-NEXT:    movw $42, (%eax)57; X32-NEXT:    retl58  store atomic i16 42, ptr %p monotonic, align 259  ret void60}61 62define void @store_atomic_imm_32(ptr %p) {63; X64-LABEL: store_atomic_imm_32:64; X64:       # %bb.0:65; X64-NEXT:    movl $42, (%rdi)66; X64-NEXT:    retq67;68; X32-LABEL: store_atomic_imm_32:69; X32:       # %bb.0:70; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax71; X32-NEXT:    movl $42, (%eax)72; X32-NEXT:    retl73;   On 32 bits, there is an extra movl for each of those functions74;   (probably for alignment reasons).75  store atomic i32 42, ptr %p release, align 476  ret void77}78 79define void @store_atomic_imm_64(ptr %p) {80; X64-LABEL: store_atomic_imm_64:81; X64:       # %bb.0:82; X64-NEXT:    movq $42, (%rdi)83; X64-NEXT:    retq84;85; X32-LABEL: store_atomic_imm_64:86; X32:       # %bb.0:87; X32-NEXT:    pushl %ebp88; X32-NEXT:    .cfi_def_cfa_offset 889; X32-NEXT:    .cfi_offset %ebp, -890; X32-NEXT:    movl %esp, %ebp91; X32-NEXT:    .cfi_def_cfa_register %ebp92; X32-NEXT:    andl $-8, %esp93; X32-NEXT:    subl $8, %esp94; X32-NEXT:    movl 8(%ebp), %eax95; X32-NEXT:    movl $0, {{[0-9]+}}(%esp)96; X32-NEXT:    movl $42, (%esp)97; X32-NEXT:    fildll (%esp)98; X32-NEXT:    fistpll (%eax)99; X32-NEXT:    movl %ebp, %esp100; X32-NEXT:    popl %ebp101; X32-NEXT:    .cfi_def_cfa %esp, 4102; X32-NEXT:    retl103;   These are implemented with a CAS loop on 32 bit architectures, and thus104;   cannot be optimized in the same way as the others.105  store atomic i64 42, ptr %p release, align 8106  ret void107}108 109; If an immediate is too big to fit in 32 bits, it cannot be store in one mov,110; even on X64, one must use movabsq that can only target a register.111define void @store_atomic_imm_64_big(ptr %p) {112; X64-LABEL: store_atomic_imm_64_big:113; X64:       # %bb.0:114; X64-NEXT:    movabsq $100000000000, %rax # imm = 0x174876E800115; X64-NEXT:    movq %rax, (%rdi)116; X64-NEXT:    retq117;118; X32-LABEL: store_atomic_imm_64_big:119; X32:       # %bb.0:120; X32-NEXT:    pushl %ebp121; X32-NEXT:    .cfi_def_cfa_offset 8122; X32-NEXT:    .cfi_offset %ebp, -8123; X32-NEXT:    movl %esp, %ebp124; X32-NEXT:    .cfi_def_cfa_register %ebp125; X32-NEXT:    andl $-8, %esp126; X32-NEXT:    subl $8, %esp127; X32-NEXT:    movl 8(%ebp), %eax128; X32-NEXT:    movl $23, {{[0-9]+}}(%esp)129; X32-NEXT:    movl $1215752192, (%esp) # imm = 0x4876E800130; X32-NEXT:    fildll (%esp)131; X32-NEXT:    fistpll (%eax)132; X32-NEXT:    movl %ebp, %esp133; X32-NEXT:    popl %ebp134; X32-NEXT:    .cfi_def_cfa %esp, 4135; X32-NEXT:    retl136  store atomic i64 100000000000, ptr %p monotonic, align 8137  ret void138}139 140; It would be incorrect to replace a lock xchgl by a movl141define void @store_atomic_imm_32_seq_cst(ptr %p) {142; X64-LABEL: store_atomic_imm_32_seq_cst:143; X64:       # %bb.0:144; X64-NEXT:    movl $42, %eax145; X64-NEXT:    xchgl %eax, (%rdi)146; X64-NEXT:    retq147;148; X32-LABEL: store_atomic_imm_32_seq_cst:149; X32:       # %bb.0:150; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax151; X32-NEXT:    movl $42, %ecx152; X32-NEXT:    xchgl %ecx, (%eax)153; X32-NEXT:    retl154  store atomic i32 42, ptr %p seq_cst, align 4155  ret void156}157 158; ----- ADD -----159 160define void @add_8i(ptr %p) {161; X64-LABEL: add_8i:162; X64:       # %bb.0:163; X64-NEXT:    addb $2, (%rdi)164; X64-NEXT:    retq165;166; X32-LABEL: add_8i:167; X32:       # %bb.0:168; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax169; X32-NEXT:    addb $2, (%eax)170; X32-NEXT:    retl171  %1 = load atomic i8, ptr %p seq_cst, align 1172  %2 = add i8 %1, 2173  store atomic i8 %2, ptr %p release, align 1174  ret void175}176 177define void @add_8r(ptr %p, i8 %v) {178; X64-LABEL: add_8r:179; X64:       # %bb.0:180; X64-NEXT:    addb %sil, (%rdi)181; X64-NEXT:    retq182;183; X32-LABEL: add_8r:184; X32:       # %bb.0:185; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax186; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx187; X32-NEXT:    addb %al, (%ecx)188; X32-NEXT:    retl189  %1 = load atomic i8, ptr %p seq_cst, align 1190  %2 = add i8 %1, %v191  store atomic i8 %2, ptr %p release, align 1192  ret void193}194 195define void @add_16i(ptr %p) {196; X64-LABEL: add_16i:197; X64:       # %bb.0:198; X64-NEXT:    addw $2, (%rdi)199; X64-NEXT:    retq200;201; X32-LABEL: add_16i:202; X32:       # %bb.0:203; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax204; X32-NEXT:    addw $2, (%eax)205; X32-NEXT:    retl206  %1 = load atomic i16, ptr %p acquire, align 2207  %2 = add i16 %1, 2208  store atomic i16 %2, ptr %p release, align 2209  ret void210}211 212define void @add_16r(ptr %p, i16 %v) {213; X64-LABEL: add_16r:214; X64:       # %bb.0:215; X64-NEXT:    addw %si, (%rdi)216; X64-NEXT:    retq217;218; X32-LABEL: add_16r:219; X32:       # %bb.0:220; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax221; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx222; X32-NEXT:    addw %ax, (%ecx)223; X32-NEXT:    retl224  %1 = load atomic i16, ptr %p acquire, align 2225  %2 = add i16 %1, %v226  store atomic i16 %2, ptr %p release, align 2227  ret void228}229 230define void @add_32i(ptr %p) {231; X64-LABEL: add_32i:232; X64:       # %bb.0:233; X64-NEXT:    addl $2, (%rdi)234; X64-NEXT:    retq235;236; X32-LABEL: add_32i:237; X32:       # %bb.0:238; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax239; X32-NEXT:    addl $2, (%eax)240; X32-NEXT:    retl241  %1 = load atomic i32, ptr %p acquire, align 4242  %2 = add i32 %1, 2243  store atomic i32 %2, ptr %p monotonic, align 4244  ret void245}246 247define void @add_32r(ptr %p, i32 %v) {248; X64-LABEL: add_32r:249; X64:       # %bb.0:250; X64-NEXT:    addl %esi, (%rdi)251; X64-NEXT:    retq252;253; X32-LABEL: add_32r:254; X32:       # %bb.0:255; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax256; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx257; X32-NEXT:    addl %eax, (%ecx)258; X32-NEXT:    retl259  %1 = load atomic i32, ptr %p acquire, align 4260  %2 = add i32 %1, %v261  store atomic i32 %2, ptr %p monotonic, align 4262  ret void263}264 265; The following is a corner case where the load is added to itself. The pattern266; matching should not fold this. We only test with 32-bit add, but the same267; applies to other sizes and operations.268define void @add_32r_self(ptr %p) {269; X64-LABEL: add_32r_self:270; X64:       # %bb.0:271; X64-NEXT:    movl (%rdi), %eax272; X64-NEXT:    addl %eax, %eax273; X64-NEXT:    movl %eax, (%rdi)274; X64-NEXT:    retq275;276; X32-LABEL: add_32r_self:277; X32:       # %bb.0:278; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax279; X32-NEXT:    movl (%eax), %ecx280; X32-NEXT:    addl %ecx, %ecx281; X32-NEXT:    movl %ecx, (%eax)282; X32-NEXT:    retl283  %1 = load atomic i32, ptr %p acquire, align 4284  %2 = add i32 %1, %1285  store atomic i32 %2, ptr %p monotonic, align 4286  ret void287}288 289; The following is a corner case where the load's result is returned. The290; optimizer isn't allowed to duplicate the load because it's atomic.291define i32 @add_32r_ret_load(ptr %p, i32 %v) {292; X64-LABEL: add_32r_ret_load:293; X64:       # %bb.0:294; X64-NEXT:    movl (%rdi), %eax295; X64-NEXT:    addl %eax, %esi296; X64-NEXT:    movl %esi, (%rdi)297; X64-NEXT:    retq298;299; X32-LABEL: add_32r_ret_load:300; X32:       # %bb.0:301; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx302; X32-NEXT:    movl (%ecx), %eax303; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx304; X32-NEXT:    addl %eax, %edx305; X32-NEXT:    movl %edx, (%ecx)306; X32-NEXT:    retl307; More code here, we just don't want it to load from P.308  %1 = load atomic i32, ptr %p acquire, align 4309  %2 = add i32 %1, %v310  store atomic i32 %2, ptr %p monotonic, align 4311  ret i32 %1312}313 314define void @add_64i(ptr %p) {315; X64-LABEL: add_64i:316; X64:       # %bb.0:317; X64-NEXT:    addq $2, (%rdi)318; X64-NEXT:    retq319;320; X32-LABEL: add_64i:321; X32:       # %bb.0:322; X32-NEXT:    pushl %ebp323; X32-NEXT:    .cfi_def_cfa_offset 8324; X32-NEXT:    .cfi_offset %ebp, -8325; X32-NEXT:    movl %esp, %ebp326; X32-NEXT:    .cfi_def_cfa_register %ebp327; X32-NEXT:    andl $-8, %esp328; X32-NEXT:    subl $16, %esp329; X32-NEXT:    movl 8(%ebp), %eax330; X32-NEXT:    fildll (%eax)331; X32-NEXT:    fistpll {{[0-9]+}}(%esp)332; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx333; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx334; X32-NEXT:    addl $2, %ecx335; X32-NEXT:    adcl $0, %edx336; X32-NEXT:    movl %ecx, (%esp)337; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)338; X32-NEXT:    fildll (%esp)339; X32-NEXT:    fistpll (%eax)340; X32-NEXT:    movl %ebp, %esp341; X32-NEXT:    popl %ebp342; X32-NEXT:    .cfi_def_cfa %esp, 4343; X32-NEXT:    retl344;   We do not check X86-32 as it cannot do 'addq'.345  %1 = load atomic i64, ptr %p acquire, align 8346  %2 = add i64 %1, 2347  store atomic i64 %2, ptr %p release, align 8348  ret void349}350 351define void @add_64r(ptr %p, i64 %v) {352; X64-LABEL: add_64r:353; X64:       # %bb.0:354; X64-NEXT:    addq %rsi, (%rdi)355; X64-NEXT:    retq356;357; X32-LABEL: add_64r:358; X32:       # %bb.0:359; X32-NEXT:    pushl %ebp360; X32-NEXT:    .cfi_def_cfa_offset 8361; X32-NEXT:    .cfi_offset %ebp, -8362; X32-NEXT:    movl %esp, %ebp363; X32-NEXT:    .cfi_def_cfa_register %ebp364; X32-NEXT:    andl $-8, %esp365; X32-NEXT:    subl $16, %esp366; X32-NEXT:    movl 8(%ebp), %eax367; X32-NEXT:    fildll (%eax)368; X32-NEXT:    fistpll {{[0-9]+}}(%esp)369; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx370; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx371; X32-NEXT:    addl 12(%ebp), %ecx372; X32-NEXT:    adcl 16(%ebp), %edx373; X32-NEXT:    movl %ecx, (%esp)374; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)375; X32-NEXT:    fildll (%esp)376; X32-NEXT:    fistpll (%eax)377; X32-NEXT:    movl %ebp, %esp378; X32-NEXT:    popl %ebp379; X32-NEXT:    .cfi_def_cfa %esp, 4380; X32-NEXT:    retl381;   We do not check X86-32 as it cannot do 'addq'.382  %1 = load atomic i64, ptr %p acquire, align 8383  %2 = add i64 %1, %v384  store atomic i64 %2, ptr %p release, align 8385  ret void386}387 388define void @add_32i_seq_cst(ptr %p) {389; X64-LABEL: add_32i_seq_cst:390; X64:       # %bb.0:391; X64-NEXT:    movl (%rdi), %eax392; X64-NEXT:    addl $2, %eax393; X64-NEXT:    xchgl %eax, (%rdi)394; X64-NEXT:    retq395;396; X32-LABEL: add_32i_seq_cst:397; X32:       # %bb.0:398; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax399; X32-NEXT:    movl (%eax), %ecx400; X32-NEXT:    addl $2, %ecx401; X32-NEXT:    xchgl %ecx, (%eax)402; X32-NEXT:    retl403  %1 = load atomic i32, ptr %p monotonic, align 4404  %2 = add i32 %1, 2405  store atomic i32 %2, ptr %p seq_cst, align 4406  ret void407}408 409define void @add_32r_seq_cst(ptr %p, i32 %v) {410; X64-LABEL: add_32r_seq_cst:411; X64:       # %bb.0:412; X64-NEXT:    movl (%rdi), %eax413; X64-NEXT:    addl %esi, %eax414; X64-NEXT:    xchgl %eax, (%rdi)415; X64-NEXT:    retq416;417; X32-LABEL: add_32r_seq_cst:418; X32:       # %bb.0:419; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax420; X32-NEXT:    movl (%eax), %ecx421; X32-NEXT:    addl {{[0-9]+}}(%esp), %ecx422; X32-NEXT:    xchgl %ecx, (%eax)423; X32-NEXT:    retl424  %1 = load atomic i32, ptr %p monotonic, align 4425  %2 = add i32 %1, %v426  store atomic i32 %2, ptr %p seq_cst, align 4427  ret void428}429 430; ----- SUB -----431 432define void @sub_8r(ptr %p, i8 %v) {433; X64-LABEL: sub_8r:434; X64:       # %bb.0:435; X64-NEXT:    subb %sil, (%rdi)436; X64-NEXT:    retq437;438; X32-LABEL: sub_8r:439; X32:       # %bb.0:440; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax441; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx442; X32-NEXT:    subb %al, (%ecx)443; X32-NEXT:    retl444  %1 = load atomic i8, ptr %p seq_cst, align 1445  %2 = sub i8 %1, %v446  store atomic i8 %2, ptr %p release, align 1447  ret void448}449 450define void @sub_16r(ptr %p, i16 %v) {451; X64-LABEL: sub_16r:452; X64:       # %bb.0:453; X64-NEXT:    subw %si, (%rdi)454; X64-NEXT:    retq455;456; X32-LABEL: sub_16r:457; X32:       # %bb.0:458; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax459; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx460; X32-NEXT:    subw %ax, (%ecx)461; X32-NEXT:    retl462  %1 = load atomic i16, ptr %p acquire, align 2463  %2 = sub i16 %1, %v464  store atomic i16 %2, ptr %p release, align 2465  ret void466}467 468define void @sub_32r(ptr %p, i32 %v) {469; X64-LABEL: sub_32r:470; X64:       # %bb.0:471; X64-NEXT:    subl %esi, (%rdi)472; X64-NEXT:    retq473;474; X32-LABEL: sub_32r:475; X32:       # %bb.0:476; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax477; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx478; X32-NEXT:    subl %eax, (%ecx)479; X32-NEXT:    retl480  %1 = load atomic i32, ptr %p acquire, align 4481  %2 = sub i32 %1, %v482  store atomic i32 %2, ptr %p monotonic, align 4483  ret void484}485 486; The following is a corner case where the load is subed to itself. The pattern487; matching should not fold this. We only test with 32-bit sub, but the same488; applies to other sizes and operations.489define void @sub_32r_self(ptr %p) {490; X64-LABEL: sub_32r_self:491; X64:       # %bb.0:492; X64-NEXT:    movl (%rdi), %eax493; X64-NEXT:    movl $0, (%rdi)494; X64-NEXT:    retq495;496; X32-LABEL: sub_32r_self:497; X32:       # %bb.0:498; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax499; X32-NEXT:    movl (%eax), %ecx500; X32-NEXT:    movl $0, (%eax)501; X32-NEXT:    retl502  %1 = load atomic i32, ptr %p acquire, align 4503  %2 = sub i32 %1, %1504  store atomic i32 %2, ptr %p monotonic, align 4505  ret void506}507 508; The following is a corner case where the load's result is returned. The509; optimizer isn't allowed to duplicate the load because it's atomic.510define i32 @sub_32r_ret_load(ptr %p, i32 %v) {511; X64-LABEL: sub_32r_ret_load:512; X64:       # %bb.0:513; X64-NEXT:    movl (%rdi), %eax514; X64-NEXT:    movl %eax, %ecx515; X64-NEXT:    subl %esi, %ecx516; X64-NEXT:    movl %ecx, (%rdi)517; X64-NEXT:    retq518;519; X32-LABEL: sub_32r_ret_load:520; X32:       # %bb.0:521; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx522; X32-NEXT:    movl (%ecx), %eax523; X32-NEXT:    movl %eax, %edx524; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx525; X32-NEXT:    movl %edx, (%ecx)526; X32-NEXT:    retl527; More code here, we just don't want it to load from P.528  %1 = load atomic i32, ptr %p acquire, align 4529  %2 = sub i32 %1, %v530  store atomic i32 %2, ptr %p monotonic, align 4531  ret i32 %1532}533 534define void @sub_64r(ptr %p, i64 %v) {535; X64-LABEL: sub_64r:536; X64:       # %bb.0:537; X64-NEXT:    subq %rsi, (%rdi)538; X64-NEXT:    retq539;540; X32-LABEL: sub_64r:541; X32:       # %bb.0:542; X32-NEXT:    pushl %ebp543; X32-NEXT:    .cfi_def_cfa_offset 8544; X32-NEXT:    .cfi_offset %ebp, -8545; X32-NEXT:    movl %esp, %ebp546; X32-NEXT:    .cfi_def_cfa_register %ebp547; X32-NEXT:    andl $-8, %esp548; X32-NEXT:    subl $16, %esp549; X32-NEXT:    movl 8(%ebp), %eax550; X32-NEXT:    fildll (%eax)551; X32-NEXT:    fistpll {{[0-9]+}}(%esp)552; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx553; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx554; X32-NEXT:    subl 12(%ebp), %ecx555; X32-NEXT:    sbbl 16(%ebp), %edx556; X32-NEXT:    movl %ecx, (%esp)557; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)558; X32-NEXT:    fildll (%esp)559; X32-NEXT:    fistpll (%eax)560; X32-NEXT:    movl %ebp, %esp561; X32-NEXT:    popl %ebp562; X32-NEXT:    .cfi_def_cfa %esp, 4563; X32-NEXT:    retl564;   We do not check X86-32 as it cannot do 'subq'.565  %1 = load atomic i64, ptr %p acquire, align 8566  %2 = sub i64 %1, %v567  store atomic i64 %2, ptr %p release, align 8568  ret void569}570 571define void @sub_32r_seq_cst(ptr %p, i32 %v) {572; X64-LABEL: sub_32r_seq_cst:573; X64:       # %bb.0:574; X64-NEXT:    movl (%rdi), %eax575; X64-NEXT:    subl %esi, %eax576; X64-NEXT:    xchgl %eax, (%rdi)577; X64-NEXT:    retq578;579; X32-LABEL: sub_32r_seq_cst:580; X32:       # %bb.0:581; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax582; X32-NEXT:    movl (%eax), %ecx583; X32-NEXT:    subl {{[0-9]+}}(%esp), %ecx584; X32-NEXT:    xchgl %ecx, (%eax)585; X32-NEXT:    retl586  %1 = load atomic i32, ptr %p monotonic, align 4587  %2 = sub i32 %1, %v588  store atomic i32 %2, ptr %p seq_cst, align 4589  ret void590}591 592; ----- AND -----593 594define void @and_8i(ptr %p) {595; X64-LABEL: and_8i:596; X64:       # %bb.0:597; X64-NEXT:    andb $2, (%rdi)598; X64-NEXT:    retq599;600; X32-LABEL: and_8i:601; X32:       # %bb.0:602; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax603; X32-NEXT:    andb $2, (%eax)604; X32-NEXT:    retl605  %1 = load atomic i8, ptr %p monotonic, align 1606  %2 = and i8 %1, 2607  store atomic i8 %2, ptr %p release, align 1608  ret void609}610 611define void @and_8r(ptr %p, i8 %v) {612; X64-LABEL: and_8r:613; X64:       # %bb.0:614; X64-NEXT:    andb %sil, (%rdi)615; X64-NEXT:    retq616;617; X32-LABEL: and_8r:618; X32:       # %bb.0:619; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax620; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx621; X32-NEXT:    andb %al, (%ecx)622; X32-NEXT:    retl623  %1 = load atomic i8, ptr %p monotonic, align 1624  %2 = and i8 %1, %v625  store atomic i8 %2, ptr %p release, align 1626  ret void627}628 629define void @and_16i(ptr %p) {630; X64-LABEL: and_16i:631; X64:       # %bb.0:632; X64-NEXT:    andw $2, (%rdi)633; X64-NEXT:    retq634;635; X32-LABEL: and_16i:636; X32:       # %bb.0:637; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax638; X32-NEXT:    andw $2, (%eax)639; X32-NEXT:    retl640  %1 = load atomic i16, ptr %p acquire, align 2641  %2 = and i16 %1, 2642  store atomic i16 %2, ptr %p release, align 2643  ret void644}645 646define void @and_16r(ptr %p, i16 %v) {647; X64-LABEL: and_16r:648; X64:       # %bb.0:649; X64-NEXT:    andw %si, (%rdi)650; X64-NEXT:    retq651;652; X32-LABEL: and_16r:653; X32:       # %bb.0:654; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax655; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx656; X32-NEXT:    andw %ax, (%ecx)657; X32-NEXT:    retl658  %1 = load atomic i16, ptr %p acquire, align 2659  %2 = and i16 %1, %v660  store atomic i16 %2, ptr %p release, align 2661  ret void662}663 664define void @and_32i(ptr %p) {665; X64-LABEL: and_32i:666; X64:       # %bb.0:667; X64-NEXT:    andl $2, (%rdi)668; X64-NEXT:    retq669;670; X32-LABEL: and_32i:671; X32:       # %bb.0:672; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax673; X32-NEXT:    andl $2, (%eax)674; X32-NEXT:    retl675  %1 = load atomic i32, ptr %p acquire, align 4676  %2 = and i32 %1, 2677  store atomic i32 %2, ptr %p release, align 4678  ret void679}680 681define void @and_32r(ptr %p, i32 %v) {682; X64-LABEL: and_32r:683; X64:       # %bb.0:684; X64-NEXT:    andl %esi, (%rdi)685; X64-NEXT:    retq686;687; X32-LABEL: and_32r:688; X32:       # %bb.0:689; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax690; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx691; X32-NEXT:    andl %eax, (%ecx)692; X32-NEXT:    retl693  %1 = load atomic i32, ptr %p acquire, align 4694  %2 = and i32 %1, %v695  store atomic i32 %2, ptr %p release, align 4696  ret void697}698 699define void @and_64i(ptr %p) {700; X64-LABEL: and_64i:701; X64:       # %bb.0:702; X64-NEXT:    andq $2, (%rdi)703; X64-NEXT:    retq704;705; X32-LABEL: and_64i:706; X32:       # %bb.0:707; X32-NEXT:    pushl %ebp708; X32-NEXT:    .cfi_def_cfa_offset 8709; X32-NEXT:    .cfi_offset %ebp, -8710; X32-NEXT:    movl %esp, %ebp711; X32-NEXT:    .cfi_def_cfa_register %ebp712; X32-NEXT:    andl $-8, %esp713; X32-NEXT:    subl $16, %esp714; X32-NEXT:    movl 8(%ebp), %eax715; X32-NEXT:    fildll (%eax)716; X32-NEXT:    fistpll {{[0-9]+}}(%esp)717; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx718; X32-NEXT:    andl $2, %ecx719; X32-NEXT:    movl %ecx, (%esp)720; X32-NEXT:    movl $0, {{[0-9]+}}(%esp)721; X32-NEXT:    fildll (%esp)722; X32-NEXT:    fistpll (%eax)723; X32-NEXT:    movl %ebp, %esp724; X32-NEXT:    popl %ebp725; X32-NEXT:    .cfi_def_cfa %esp, 4726; X32-NEXT:    retl727;   We do not check X86-32 as it cannot do 'andq'.728  %1 = load atomic i64, ptr %p acquire, align 8729  %2 = and i64 %1, 2730  store atomic i64 %2, ptr %p release, align 8731  ret void732}733 734define void @and_64r(ptr %p, i64 %v) {735; X64-LABEL: and_64r:736; X64:       # %bb.0:737; X64-NEXT:    andq %rsi, (%rdi)738; X64-NEXT:    retq739;740; X32-LABEL: and_64r:741; X32:       # %bb.0:742; X32-NEXT:    pushl %ebp743; X32-NEXT:    .cfi_def_cfa_offset 8744; X32-NEXT:    .cfi_offset %ebp, -8745; X32-NEXT:    movl %esp, %ebp746; X32-NEXT:    .cfi_def_cfa_register %ebp747; X32-NEXT:    andl $-8, %esp748; X32-NEXT:    subl $16, %esp749; X32-NEXT:    movl 8(%ebp), %eax750; X32-NEXT:    fildll (%eax)751; X32-NEXT:    fistpll {{[0-9]+}}(%esp)752; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx753; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx754; X32-NEXT:    andl 16(%ebp), %edx755; X32-NEXT:    andl 12(%ebp), %ecx756; X32-NEXT:    movl %ecx, (%esp)757; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)758; X32-NEXT:    fildll (%esp)759; X32-NEXT:    fistpll (%eax)760; X32-NEXT:    movl %ebp, %esp761; X32-NEXT:    popl %ebp762; X32-NEXT:    .cfi_def_cfa %esp, 4763; X32-NEXT:    retl764;   We do not check X86-32 as it cannot do 'andq'.765  %1 = load atomic i64, ptr %p acquire, align 8766  %2 = and i64 %1, %v767  store atomic i64 %2, ptr %p release, align 8768  ret void769}770 771define void @and_32i_seq_cst(ptr %p) {772; X64-LABEL: and_32i_seq_cst:773; X64:       # %bb.0:774; X64-NEXT:    movl (%rdi), %eax775; X64-NEXT:    andl $2, %eax776; X64-NEXT:    xchgl %eax, (%rdi)777; X64-NEXT:    retq778;779; X32-LABEL: and_32i_seq_cst:780; X32:       # %bb.0:781; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax782; X32-NEXT:    movl (%eax), %ecx783; X32-NEXT:    andl $2, %ecx784; X32-NEXT:    xchgl %ecx, (%eax)785; X32-NEXT:    retl786  %1 = load atomic i32, ptr %p monotonic, align 4787  %2 = and i32 %1, 2788  store atomic i32 %2, ptr %p seq_cst, align 4789  ret void790}791 792define void @and_32r_seq_cst(ptr %p, i32 %v) {793; X64-LABEL: and_32r_seq_cst:794; X64:       # %bb.0:795; X64-NEXT:    movl (%rdi), %eax796; X64-NEXT:    andl %esi, %eax797; X64-NEXT:    xchgl %eax, (%rdi)798; X64-NEXT:    retq799;800; X32-LABEL: and_32r_seq_cst:801; X32:       # %bb.0:802; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax803; X32-NEXT:    movl (%eax), %ecx804; X32-NEXT:    andl {{[0-9]+}}(%esp), %ecx805; X32-NEXT:    xchgl %ecx, (%eax)806; X32-NEXT:    retl807  %1 = load atomic i32, ptr %p monotonic, align 4808  %2 = and i32 %1, %v809  store atomic i32 %2, ptr %p seq_cst, align 4810  ret void811}812 813; ----- OR -----814 815define void @or_8i(ptr %p) {816; X64-LABEL: or_8i:817; X64:       # %bb.0:818; X64-NEXT:    orb $2, (%rdi)819; X64-NEXT:    retq820;821; X32-LABEL: or_8i:822; X32:       # %bb.0:823; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax824; X32-NEXT:    orb $2, (%eax)825; X32-NEXT:    retl826  %1 = load atomic i8, ptr %p acquire, align 1827  %2 = or i8 %1, 2828  store atomic i8 %2, ptr %p release, align 1829  ret void830}831 832define void @or_8r(ptr %p, i8 %v) {833; X64-LABEL: or_8r:834; X64:       # %bb.0:835; X64-NEXT:    orb %sil, (%rdi)836; X64-NEXT:    retq837;838; X32-LABEL: or_8r:839; X32:       # %bb.0:840; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax841; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx842; X32-NEXT:    orb %al, (%ecx)843; X32-NEXT:    retl844  %1 = load atomic i8, ptr %p acquire, align 1845  %2 = or i8 %1, %v846  store atomic i8 %2, ptr %p release, align 1847  ret void848}849 850define void @or_16i(ptr %p) {851; X64-LABEL: or_16i:852; X64:       # %bb.0:853; X64-NEXT:    orw $2, (%rdi)854; X64-NEXT:    retq855;856; X32-LABEL: or_16i:857; X32:       # %bb.0:858; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax859; X32-NEXT:    orw $2, (%eax)860; X32-NEXT:    retl861  %1 = load atomic i16, ptr %p acquire, align 2862  %2 = or i16 %1, 2863  store atomic i16 %2, ptr %p release, align 2864  ret void865}866 867define void @or_16r(ptr %p, i16 %v) {868; X64-LABEL: or_16r:869; X64:       # %bb.0:870; X64-NEXT:    orw %si, (%rdi)871; X64-NEXT:    retq872;873; X32-LABEL: or_16r:874; X32:       # %bb.0:875; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax876; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx877; X32-NEXT:    orw %ax, (%ecx)878; X32-NEXT:    retl879  %1 = load atomic i16, ptr %p acquire, align 2880  %2 = or i16 %1, %v881  store atomic i16 %2, ptr %p release, align 2882  ret void883}884 885define void @or_32i(ptr %p) {886; X64-LABEL: or_32i:887; X64:       # %bb.0:888; X64-NEXT:    orl $2, (%rdi)889; X64-NEXT:    retq890;891; X32-LABEL: or_32i:892; X32:       # %bb.0:893; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax894; X32-NEXT:    orl $2, (%eax)895; X32-NEXT:    retl896  %1 = load atomic i32, ptr %p acquire, align 4897  %2 = or i32 %1, 2898  store atomic i32 %2, ptr %p release, align 4899  ret void900}901 902define void @or_32r(ptr %p, i32 %v) {903; X64-LABEL: or_32r:904; X64:       # %bb.0:905; X64-NEXT:    orl %esi, (%rdi)906; X64-NEXT:    retq907;908; X32-LABEL: or_32r:909; X32:       # %bb.0:910; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax911; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx912; X32-NEXT:    orl %eax, (%ecx)913; X32-NEXT:    retl914  %1 = load atomic i32, ptr %p acquire, align 4915  %2 = or i32 %1, %v916  store atomic i32 %2, ptr %p release, align 4917  ret void918}919 920define void @or_64i(ptr %p) {921; X64-LABEL: or_64i:922; X64:       # %bb.0:923; X64-NEXT:    orq $2, (%rdi)924; X64-NEXT:    retq925;926; X32-LABEL: or_64i:927; X32:       # %bb.0:928; X32-NEXT:    pushl %ebp929; X32-NEXT:    .cfi_def_cfa_offset 8930; X32-NEXT:    .cfi_offset %ebp, -8931; X32-NEXT:    movl %esp, %ebp932; X32-NEXT:    .cfi_def_cfa_register %ebp933; X32-NEXT:    andl $-8, %esp934; X32-NEXT:    subl $16, %esp935; X32-NEXT:    movl 8(%ebp), %eax936; X32-NEXT:    fildll (%eax)937; X32-NEXT:    fistpll {{[0-9]+}}(%esp)938; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx939; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx940; X32-NEXT:    orl $2, %ecx941; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)942; X32-NEXT:    movl %ecx, (%esp)943; X32-NEXT:    fildll (%esp)944; X32-NEXT:    fistpll (%eax)945; X32-NEXT:    movl %ebp, %esp946; X32-NEXT:    popl %ebp947; X32-NEXT:    .cfi_def_cfa %esp, 4948; X32-NEXT:    retl949;   We do not check X86-32 as it cannot do 'orq'.950  %1 = load atomic i64, ptr %p acquire, align 8951  %2 = or i64 %1, 2952  store atomic i64 %2, ptr %p release, align 8953  ret void954}955 956define void @or_64r(ptr %p, i64 %v) {957; X64-LABEL: or_64r:958; X64:       # %bb.0:959; X64-NEXT:    orq %rsi, (%rdi)960; X64-NEXT:    retq961;962; X32-LABEL: or_64r:963; X32:       # %bb.0:964; X32-NEXT:    pushl %ebp965; X32-NEXT:    .cfi_def_cfa_offset 8966; X32-NEXT:    .cfi_offset %ebp, -8967; X32-NEXT:    movl %esp, %ebp968; X32-NEXT:    .cfi_def_cfa_register %ebp969; X32-NEXT:    andl $-8, %esp970; X32-NEXT:    subl $16, %esp971; X32-NEXT:    movl 8(%ebp), %eax972; X32-NEXT:    fildll (%eax)973; X32-NEXT:    fistpll {{[0-9]+}}(%esp)974; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx975; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx976; X32-NEXT:    orl 16(%ebp), %edx977; X32-NEXT:    orl 12(%ebp), %ecx978; X32-NEXT:    movl %ecx, (%esp)979; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)980; X32-NEXT:    fildll (%esp)981; X32-NEXT:    fistpll (%eax)982; X32-NEXT:    movl %ebp, %esp983; X32-NEXT:    popl %ebp984; X32-NEXT:    .cfi_def_cfa %esp, 4985; X32-NEXT:    retl986;   We do not check X86-32 as it cannot do 'orq'.987  %1 = load atomic i64, ptr %p acquire, align 8988  %2 = or i64 %1, %v989  store atomic i64 %2, ptr %p release, align 8990  ret void991}992 993define void @or_32i_seq_cst(ptr %p) {994; X64-LABEL: or_32i_seq_cst:995; X64:       # %bb.0:996; X64-NEXT:    movl (%rdi), %eax997; X64-NEXT:    orl $2, %eax998; X64-NEXT:    xchgl %eax, (%rdi)999; X64-NEXT:    retq1000;1001; X32-LABEL: or_32i_seq_cst:1002; X32:       # %bb.0:1003; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1004; X32-NEXT:    movl (%eax), %ecx1005; X32-NEXT:    orl $2, %ecx1006; X32-NEXT:    xchgl %ecx, (%eax)1007; X32-NEXT:    retl1008  %1 = load atomic i32, ptr %p monotonic, align 41009  %2 = or i32 %1, 21010  store atomic i32 %2, ptr %p seq_cst, align 41011  ret void1012}1013 1014define void @or_32r_seq_cst(ptr %p, i32 %v) {1015; X64-LABEL: or_32r_seq_cst:1016; X64:       # %bb.0:1017; X64-NEXT:    movl (%rdi), %eax1018; X64-NEXT:    orl %esi, %eax1019; X64-NEXT:    xchgl %eax, (%rdi)1020; X64-NEXT:    retq1021;1022; X32-LABEL: or_32r_seq_cst:1023; X32:       # %bb.0:1024; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1025; X32-NEXT:    movl (%eax), %ecx1026; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx1027; X32-NEXT:    xchgl %ecx, (%eax)1028; X32-NEXT:    retl1029  %1 = load atomic i32, ptr %p monotonic, align 41030  %2 = or i32 %1, %v1031  store atomic i32 %2, ptr %p seq_cst, align 41032  ret void1033}1034 1035; ----- XOR -----1036 1037define void @xor_8i(ptr %p) {1038; X64-LABEL: xor_8i:1039; X64:       # %bb.0:1040; X64-NEXT:    xorb $2, (%rdi)1041; X64-NEXT:    retq1042;1043; X32-LABEL: xor_8i:1044; X32:       # %bb.0:1045; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1046; X32-NEXT:    xorb $2, (%eax)1047; X32-NEXT:    retl1048  %1 = load atomic i8, ptr %p acquire, align 11049  %2 = xor i8 %1, 21050  store atomic i8 %2, ptr %p release, align 11051  ret void1052}1053 1054define void @xor_8r(ptr %p, i8 %v) {1055; X64-LABEL: xor_8r:1056; X64:       # %bb.0:1057; X64-NEXT:    xorb %sil, (%rdi)1058; X64-NEXT:    retq1059;1060; X32-LABEL: xor_8r:1061; X32:       # %bb.0:1062; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax1063; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1064; X32-NEXT:    xorb %al, (%ecx)1065; X32-NEXT:    retl1066  %1 = load atomic i8, ptr %p acquire, align 11067  %2 = xor i8 %1, %v1068  store atomic i8 %2, ptr %p release, align 11069  ret void1070}1071 1072define void @xor_16i(ptr %p) {1073; X64-LABEL: xor_16i:1074; X64:       # %bb.0:1075; X64-NEXT:    xorw $2, (%rdi)1076; X64-NEXT:    retq1077;1078; X32-LABEL: xor_16i:1079; X32:       # %bb.0:1080; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1081; X32-NEXT:    xorw $2, (%eax)1082; X32-NEXT:    retl1083  %1 = load atomic i16, ptr %p acquire, align 21084  %2 = xor i16 %1, 21085  store atomic i16 %2, ptr %p release, align 21086  ret void1087}1088 1089define void @xor_16r(ptr %p, i16 %v) {1090; X64-LABEL: xor_16r:1091; X64:       # %bb.0:1092; X64-NEXT:    xorw %si, (%rdi)1093; X64-NEXT:    retq1094;1095; X32-LABEL: xor_16r:1096; X32:       # %bb.0:1097; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax1098; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1099; X32-NEXT:    xorw %ax, (%ecx)1100; X32-NEXT:    retl1101  %1 = load atomic i16, ptr %p acquire, align 21102  %2 = xor i16 %1, %v1103  store atomic i16 %2, ptr %p release, align 21104  ret void1105}1106 1107define void @xor_32i(ptr %p) {1108; X64-LABEL: xor_32i:1109; X64:       # %bb.0:1110; X64-NEXT:    xorl $2, (%rdi)1111; X64-NEXT:    retq1112;1113; X32-LABEL: xor_32i:1114; X32:       # %bb.0:1115; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1116; X32-NEXT:    xorl $2, (%eax)1117; X32-NEXT:    retl1118  %1 = load atomic i32, ptr %p acquire, align 41119  %2 = xor i32 %1, 21120  store atomic i32 %2, ptr %p release, align 41121  ret void1122}1123 1124define void @xor_32r(ptr %p, i32 %v) {1125; X64-LABEL: xor_32r:1126; X64:       # %bb.0:1127; X64-NEXT:    xorl %esi, (%rdi)1128; X64-NEXT:    retq1129;1130; X32-LABEL: xor_32r:1131; X32:       # %bb.0:1132; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1133; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1134; X32-NEXT:    xorl %eax, (%ecx)1135; X32-NEXT:    retl1136  %1 = load atomic i32, ptr %p acquire, align 41137  %2 = xor i32 %1, %v1138  store atomic i32 %2, ptr %p release, align 41139  ret void1140}1141 1142define void @xor_64i(ptr %p) {1143; X64-LABEL: xor_64i:1144; X64:       # %bb.0:1145; X64-NEXT:    xorq $2, (%rdi)1146; X64-NEXT:    retq1147;1148; X32-LABEL: xor_64i:1149; X32:       # %bb.0:1150; X32-NEXT:    pushl %ebp1151; X32-NEXT:    .cfi_def_cfa_offset 81152; X32-NEXT:    .cfi_offset %ebp, -81153; X32-NEXT:    movl %esp, %ebp1154; X32-NEXT:    .cfi_def_cfa_register %ebp1155; X32-NEXT:    andl $-8, %esp1156; X32-NEXT:    subl $16, %esp1157; X32-NEXT:    movl 8(%ebp), %eax1158; X32-NEXT:    fildll (%eax)1159; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1160; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1161; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx1162; X32-NEXT:    xorl $2, %ecx1163; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)1164; X32-NEXT:    movl %ecx, (%esp)1165; X32-NEXT:    fildll (%esp)1166; X32-NEXT:    fistpll (%eax)1167; X32-NEXT:    movl %ebp, %esp1168; X32-NEXT:    popl %ebp1169; X32-NEXT:    .cfi_def_cfa %esp, 41170; X32-NEXT:    retl1171;   We do not check X86-32 as it cannot do 'xorq'.1172  %1 = load atomic i64, ptr %p acquire, align 81173  %2 = xor i64 %1, 21174  store atomic i64 %2, ptr %p release, align 81175  ret void1176}1177 1178define void @xor_64r(ptr %p, i64 %v) {1179; X64-LABEL: xor_64r:1180; X64:       # %bb.0:1181; X64-NEXT:    xorq %rsi, (%rdi)1182; X64-NEXT:    retq1183;1184; X32-LABEL: xor_64r:1185; X32:       # %bb.0:1186; X32-NEXT:    pushl %ebp1187; X32-NEXT:    .cfi_def_cfa_offset 81188; X32-NEXT:    .cfi_offset %ebp, -81189; X32-NEXT:    movl %esp, %ebp1190; X32-NEXT:    .cfi_def_cfa_register %ebp1191; X32-NEXT:    andl $-8, %esp1192; X32-NEXT:    subl $16, %esp1193; X32-NEXT:    movl 8(%ebp), %eax1194; X32-NEXT:    fildll (%eax)1195; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1196; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1197; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx1198; X32-NEXT:    xorl 16(%ebp), %edx1199; X32-NEXT:    xorl 12(%ebp), %ecx1200; X32-NEXT:    movl %ecx, (%esp)1201; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)1202; X32-NEXT:    fildll (%esp)1203; X32-NEXT:    fistpll (%eax)1204; X32-NEXT:    movl %ebp, %esp1205; X32-NEXT:    popl %ebp1206; X32-NEXT:    .cfi_def_cfa %esp, 41207; X32-NEXT:    retl1208;   We do not check X86-32 as it cannot do 'xorq'.1209  %1 = load atomic i64, ptr %p acquire, align 81210  %2 = xor i64 %1, %v1211  store atomic i64 %2, ptr %p release, align 81212  ret void1213}1214 1215define void @xor_32i_seq_cst(ptr %p) {1216; X64-LABEL: xor_32i_seq_cst:1217; X64:       # %bb.0:1218; X64-NEXT:    movl (%rdi), %eax1219; X64-NEXT:    xorl $2, %eax1220; X64-NEXT:    xchgl %eax, (%rdi)1221; X64-NEXT:    retq1222;1223; X32-LABEL: xor_32i_seq_cst:1224; X32:       # %bb.0:1225; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1226; X32-NEXT:    movl (%eax), %ecx1227; X32-NEXT:    xorl $2, %ecx1228; X32-NEXT:    xchgl %ecx, (%eax)1229; X32-NEXT:    retl1230  %1 = load atomic i32, ptr %p monotonic, align 41231  %2 = xor i32 %1, 21232  store atomic i32 %2, ptr %p seq_cst, align 41233  ret void1234}1235 1236define void @xor_32r_seq_cst(ptr %p, i32 %v) {1237; X64-LABEL: xor_32r_seq_cst:1238; X64:       # %bb.0:1239; X64-NEXT:    movl (%rdi), %eax1240; X64-NEXT:    xorl %esi, %eax1241; X64-NEXT:    xchgl %eax, (%rdi)1242; X64-NEXT:    retq1243;1244; X32-LABEL: xor_32r_seq_cst:1245; X32:       # %bb.0:1246; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1247; X32-NEXT:    movl (%eax), %ecx1248; X32-NEXT:    xorl {{[0-9]+}}(%esp), %ecx1249; X32-NEXT:    xchgl %ecx, (%eax)1250; X32-NEXT:    retl1251  %1 = load atomic i32, ptr %p monotonic, align 41252  %2 = xor i32 %1, %v1253  store atomic i32 %2, ptr %p seq_cst, align 41254  ret void1255}1256 1257; ----- INC -----1258 1259define void @inc_8(ptr %p) {1260; FAST_INC-LABEL: inc_8:1261; FAST_INC:       # %bb.0:1262; FAST_INC-NEXT:    incb (%rdi)1263; FAST_INC-NEXT:    retq1264;1265; X32-LABEL: inc_8:1266; X32:       # %bb.0:1267; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1268; X32-NEXT:    incb (%eax)1269; X32-NEXT:    retl1270;1271; SLOW_INC-LABEL: inc_8:1272; SLOW_INC:       # %bb.0:1273; SLOW_INC-NEXT:    addb $1, (%rdi)1274; SLOW_INC-NEXT:    retq1275  %1 = load atomic i8, ptr %p seq_cst, align 11276  %2 = add i8 %1, 11277  store atomic i8 %2, ptr %p release, align 11278  ret void1279}1280 1281define void @inc_16(ptr %p) {1282; FAST_INC-LABEL: inc_16:1283; FAST_INC:       # %bb.0:1284; FAST_INC-NEXT:    incw (%rdi)1285; FAST_INC-NEXT:    retq1286;1287; X32-LABEL: inc_16:1288; X32:       # %bb.0:1289; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1290; X32-NEXT:    incw (%eax)1291; X32-NEXT:    retl1292;1293; SLOW_INC-LABEL: inc_16:1294; SLOW_INC:       # %bb.0:1295; SLOW_INC-NEXT:    addw $1, (%rdi)1296; SLOW_INC-NEXT:    retq1297  %1 = load atomic i16, ptr %p acquire, align 21298  %2 = add i16 %1, 11299  store atomic i16 %2, ptr %p release, align 21300  ret void1301}1302 1303define void @inc_32(ptr %p) {1304; FAST_INC-LABEL: inc_32:1305; FAST_INC:       # %bb.0:1306; FAST_INC-NEXT:    incl (%rdi)1307; FAST_INC-NEXT:    retq1308;1309; X32-LABEL: inc_32:1310; X32:       # %bb.0:1311; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1312; X32-NEXT:    incl (%eax)1313; X32-NEXT:    retl1314;1315; SLOW_INC-LABEL: inc_32:1316; SLOW_INC:       # %bb.0:1317; SLOW_INC-NEXT:    addl $1, (%rdi)1318; SLOW_INC-NEXT:    retq1319  %1 = load atomic i32, ptr %p acquire, align 41320  %2 = add i32 %1, 11321  store atomic i32 %2, ptr %p monotonic, align 41322  ret void1323}1324 1325define void @inc_64(ptr %p) {1326; FAST_INC-LABEL: inc_64:1327; FAST_INC:       # %bb.0:1328; FAST_INC-NEXT:    incq (%rdi)1329; FAST_INC-NEXT:    retq1330;1331; X32-LABEL: inc_64:1332; X32:       # %bb.0:1333; X32-NEXT:    pushl %ebp1334; X32-NEXT:    .cfi_def_cfa_offset 81335; X32-NEXT:    .cfi_offset %ebp, -81336; X32-NEXT:    movl %esp, %ebp1337; X32-NEXT:    .cfi_def_cfa_register %ebp1338; X32-NEXT:    andl $-8, %esp1339; X32-NEXT:    subl $16, %esp1340; X32-NEXT:    movl 8(%ebp), %eax1341; X32-NEXT:    fildll (%eax)1342; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1343; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1344; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx1345; X32-NEXT:    addl $1, %ecx1346; X32-NEXT:    adcl $0, %edx1347; X32-NEXT:    movl %ecx, (%esp)1348; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)1349; X32-NEXT:    fildll (%esp)1350; X32-NEXT:    fistpll (%eax)1351; X32-NEXT:    movl %ebp, %esp1352; X32-NEXT:    popl %ebp1353; X32-NEXT:    .cfi_def_cfa %esp, 41354; X32-NEXT:    retl1355;1356; SLOW_INC-LABEL: inc_64:1357; SLOW_INC:       # %bb.0:1358; SLOW_INC-NEXT:    addq $1, (%rdi)1359; SLOW_INC-NEXT:    retq1360;   We do not check X86-32 as it cannot do 'incq'.1361  %1 = load atomic i64, ptr %p acquire, align 81362  %2 = add i64 %1, 11363  store atomic i64 %2, ptr %p release, align 81364  ret void1365}1366 1367define void @inc_32_seq_cst(ptr %p) {1368; FAST_INC-LABEL: inc_32_seq_cst:1369; FAST_INC:       # %bb.0:1370; FAST_INC-NEXT:    movl (%rdi), %eax1371; FAST_INC-NEXT:    incl %eax1372; FAST_INC-NEXT:    xchgl %eax, (%rdi)1373; FAST_INC-NEXT:    retq1374;1375; X32-LABEL: inc_32_seq_cst:1376; X32:       # %bb.0:1377; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1378; X32-NEXT:    movl (%eax), %ecx1379; X32-NEXT:    incl %ecx1380; X32-NEXT:    xchgl %ecx, (%eax)1381; X32-NEXT:    retl1382;1383; SLOW_INC-LABEL: inc_32_seq_cst:1384; SLOW_INC:       # %bb.0:1385; SLOW_INC-NEXT:    movl (%rdi), %eax1386; SLOW_INC-NEXT:    addl $1, %eax1387; SLOW_INC-NEXT:    xchgl %eax, (%rdi)1388; SLOW_INC-NEXT:    retq1389  %1 = load atomic i32, ptr %p monotonic, align 41390  %2 = add i32 %1, 11391  store atomic i32 %2, ptr %p seq_cst, align 41392  ret void1393}1394 1395; ----- DEC -----1396 1397define void @dec_8(ptr %p) {1398; FAST_INC-LABEL: dec_8:1399; FAST_INC:       # %bb.0:1400; FAST_INC-NEXT:    decb (%rdi)1401; FAST_INC-NEXT:    retq1402;1403; X32-LABEL: dec_8:1404; X32:       # %bb.0:1405; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1406; X32-NEXT:    decb (%eax)1407; X32-NEXT:    retl1408;1409; SLOW_INC-LABEL: dec_8:1410; SLOW_INC:       # %bb.0:1411; SLOW_INC-NEXT:    addb $-1, (%rdi)1412; SLOW_INC-NEXT:    retq1413  %1 = load atomic i8, ptr %p seq_cst, align 11414  %2 = sub i8 %1, 11415  store atomic i8 %2, ptr %p release, align 11416  ret void1417}1418 1419define void @dec_16(ptr %p) {1420; FAST_INC-LABEL: dec_16:1421; FAST_INC:       # %bb.0:1422; FAST_INC-NEXT:    decw (%rdi)1423; FAST_INC-NEXT:    retq1424;1425; X32-LABEL: dec_16:1426; X32:       # %bb.0:1427; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1428; X32-NEXT:    decw (%eax)1429; X32-NEXT:    retl1430;1431; SLOW_INC-LABEL: dec_16:1432; SLOW_INC:       # %bb.0:1433; SLOW_INC-NEXT:    addw $-1, (%rdi)1434; SLOW_INC-NEXT:    retq1435  %1 = load atomic i16, ptr %p acquire, align 21436  %2 = sub i16 %1, 11437  store atomic i16 %2, ptr %p release, align 21438  ret void1439}1440 1441define void @dec_32(ptr %p) {1442; FAST_INC-LABEL: dec_32:1443; FAST_INC:       # %bb.0:1444; FAST_INC-NEXT:    decl (%rdi)1445; FAST_INC-NEXT:    retq1446;1447; X32-LABEL: dec_32:1448; X32:       # %bb.0:1449; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1450; X32-NEXT:    decl (%eax)1451; X32-NEXT:    retl1452;1453; SLOW_INC-LABEL: dec_32:1454; SLOW_INC:       # %bb.0:1455; SLOW_INC-NEXT:    addl $-1, (%rdi)1456; SLOW_INC-NEXT:    retq1457  %1 = load atomic i32, ptr %p acquire, align 41458  %2 = sub i32 %1, 11459  store atomic i32 %2, ptr %p monotonic, align 41460  ret void1461}1462 1463define void @dec_64(ptr %p) {1464; FAST_INC-LABEL: dec_64:1465; FAST_INC:       # %bb.0:1466; FAST_INC-NEXT:    decq (%rdi)1467; FAST_INC-NEXT:    retq1468;1469; X32-LABEL: dec_64:1470; X32:       # %bb.0:1471; X32-NEXT:    pushl %ebp1472; X32-NEXT:    .cfi_def_cfa_offset 81473; X32-NEXT:    .cfi_offset %ebp, -81474; X32-NEXT:    movl %esp, %ebp1475; X32-NEXT:    .cfi_def_cfa_register %ebp1476; X32-NEXT:    andl $-8, %esp1477; X32-NEXT:    subl $16, %esp1478; X32-NEXT:    movl 8(%ebp), %eax1479; X32-NEXT:    fildll (%eax)1480; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1481; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1482; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx1483; X32-NEXT:    addl $-1, %ecx1484; X32-NEXT:    adcl $-1, %edx1485; X32-NEXT:    movl %ecx, (%esp)1486; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)1487; X32-NEXT:    fildll (%esp)1488; X32-NEXT:    fistpll (%eax)1489; X32-NEXT:    movl %ebp, %esp1490; X32-NEXT:    popl %ebp1491; X32-NEXT:    .cfi_def_cfa %esp, 41492; X32-NEXT:    retl1493;1494; SLOW_INC-LABEL: dec_64:1495; SLOW_INC:       # %bb.0:1496; SLOW_INC-NEXT:    addq $-1, (%rdi)1497; SLOW_INC-NEXT:    retq1498;   We do not check X86-32 as it cannot do 'decq'.1499  %1 = load atomic i64, ptr %p acquire, align 81500  %2 = sub i64 %1, 11501  store atomic i64 %2, ptr %p release, align 81502  ret void1503}1504 1505define void @dec_32_seq_cst(ptr %p) {1506; FAST_INC-LABEL: dec_32_seq_cst:1507; FAST_INC:       # %bb.0:1508; FAST_INC-NEXT:    movl (%rdi), %eax1509; FAST_INC-NEXT:    decl %eax1510; FAST_INC-NEXT:    xchgl %eax, (%rdi)1511; FAST_INC-NEXT:    retq1512;1513; X32-LABEL: dec_32_seq_cst:1514; X32:       # %bb.0:1515; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1516; X32-NEXT:    movl (%eax), %ecx1517; X32-NEXT:    decl %ecx1518; X32-NEXT:    xchgl %ecx, (%eax)1519; X32-NEXT:    retl1520;1521; SLOW_INC-LABEL: dec_32_seq_cst:1522; SLOW_INC:       # %bb.0:1523; SLOW_INC-NEXT:    movl (%rdi), %eax1524; SLOW_INC-NEXT:    addl $-1, %eax1525; SLOW_INC-NEXT:    xchgl %eax, (%rdi)1526; SLOW_INC-NEXT:    retq1527  %1 = load atomic i32, ptr %p monotonic, align 41528  %2 = sub i32 %1, 11529  store atomic i32 %2, ptr %p seq_cst, align 41530  ret void1531}1532 1533; ----- NOT -----1534 1535define void @not_8(ptr %p) {1536; X64-LABEL: not_8:1537; X64:       # %bb.0:1538; X64-NEXT:    notb (%rdi)1539; X64-NEXT:    retq1540;1541; X32-LABEL: not_8:1542; X32:       # %bb.0:1543; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1544; X32-NEXT:    notb (%eax)1545; X32-NEXT:    retl1546  %1 = load atomic i8, ptr %p seq_cst, align 11547  %2 = xor i8 %1, -11548  store atomic i8 %2, ptr %p release, align 11549  ret void1550}1551 1552define void @not_16(ptr %p) {1553; X64-LABEL: not_16:1554; X64:       # %bb.0:1555; X64-NEXT:    notw (%rdi)1556; X64-NEXT:    retq1557;1558; X32-LABEL: not_16:1559; X32:       # %bb.0:1560; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1561; X32-NEXT:    notw (%eax)1562; X32-NEXT:    retl1563  %1 = load atomic i16, ptr %p acquire, align 21564  %2 = xor i16 %1, -11565  store atomic i16 %2, ptr %p release, align 21566  ret void1567}1568 1569define void @not_32(ptr %p) {1570; X64-LABEL: not_32:1571; X64:       # %bb.0:1572; X64-NEXT:    notl (%rdi)1573; X64-NEXT:    retq1574;1575; X32-LABEL: not_32:1576; X32:       # %bb.0:1577; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1578; X32-NEXT:    notl (%eax)1579; X32-NEXT:    retl1580  %1 = load atomic i32, ptr %p acquire, align 41581  %2 = xor i32 %1, -11582  store atomic i32 %2, ptr %p monotonic, align 41583  ret void1584}1585 1586define void @not_64(ptr %p) {1587; X64-LABEL: not_64:1588; X64:       # %bb.0:1589; X64-NEXT:    notq (%rdi)1590; X64-NEXT:    retq1591;1592; X32-LABEL: not_64:1593; X32:       # %bb.0:1594; X32-NEXT:    pushl %ebp1595; X32-NEXT:    .cfi_def_cfa_offset 81596; X32-NEXT:    .cfi_offset %ebp, -81597; X32-NEXT:    movl %esp, %ebp1598; X32-NEXT:    .cfi_def_cfa_register %ebp1599; X32-NEXT:    andl $-8, %esp1600; X32-NEXT:    subl $16, %esp1601; X32-NEXT:    movl 8(%ebp), %eax1602; X32-NEXT:    fildll (%eax)1603; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1604; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx1605; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx1606; X32-NEXT:    notl %edx1607; X32-NEXT:    notl %ecx1608; X32-NEXT:    movl %ecx, (%esp)1609; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)1610; X32-NEXT:    fildll (%esp)1611; X32-NEXT:    fistpll (%eax)1612; X32-NEXT:    movl %ebp, %esp1613; X32-NEXT:    popl %ebp1614; X32-NEXT:    .cfi_def_cfa %esp, 41615; X32-NEXT:    retl1616;   We do not check X86-32 as it cannot do 'notq'.1617  %1 = load atomic i64, ptr %p acquire, align 81618  %2 = xor i64 %1, -11619  store atomic i64 %2, ptr %p release, align 81620  ret void1621}1622 1623define void @not_32_seq_cst(ptr %p) {1624; X64-LABEL: not_32_seq_cst:1625; X64:       # %bb.0:1626; X64-NEXT:    movl (%rdi), %eax1627; X64-NEXT:    notl %eax1628; X64-NEXT:    xchgl %eax, (%rdi)1629; X64-NEXT:    retq1630;1631; X32-LABEL: not_32_seq_cst:1632; X32:       # %bb.0:1633; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1634; X32-NEXT:    movl (%eax), %ecx1635; X32-NEXT:    notl %ecx1636; X32-NEXT:    xchgl %ecx, (%eax)1637; X32-NEXT:    retl1638  %1 = load atomic i32, ptr %p monotonic, align 41639  %2 = xor i32 %1, -11640  store atomic i32 %2, ptr %p seq_cst, align 41641  ret void1642}1643 1644; ----- NEG -----1645 1646define void @neg_8(ptr %p) {1647; X64-LABEL: neg_8:1648; X64:       # %bb.0:1649; X64-NEXT:    negb (%rdi)1650; X64-NEXT:    retq1651;1652; X32-LABEL: neg_8:1653; X32:       # %bb.0:1654; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1655; X32-NEXT:    negb (%eax)1656; X32-NEXT:    retl1657  %1 = load atomic i8, ptr %p seq_cst, align 11658  %2 = sub i8 0, %11659  store atomic i8 %2, ptr %p release, align 11660  ret void1661}1662 1663define void @neg_16(ptr %p) {1664; X64-LABEL: neg_16:1665; X64:       # %bb.0:1666; X64-NEXT:    movzwl (%rdi), %eax1667; X64-NEXT:    negl %eax1668; X64-NEXT:    movw %ax, (%rdi)1669; X64-NEXT:    retq1670;1671; X32-LABEL: neg_16:1672; X32:       # %bb.0:1673; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1674; X32-NEXT:    movzwl (%eax), %ecx1675; X32-NEXT:    negl %ecx1676; X32-NEXT:    movw %cx, (%eax)1677; X32-NEXT:    retl1678  %1 = load atomic i16, ptr %p acquire, align 21679  %2 = sub i16 0, %11680  store atomic i16 %2, ptr %p release, align 21681  ret void1682}1683 1684define void @neg_32(ptr %p) {1685; X64-LABEL: neg_32:1686; X64:       # %bb.0:1687; X64-NEXT:    negl (%rdi)1688; X64-NEXT:    retq1689;1690; X32-LABEL: neg_32:1691; X32:       # %bb.0:1692; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1693; X32-NEXT:    negl (%eax)1694; X32-NEXT:    retl1695  %1 = load atomic i32, ptr %p acquire, align 41696  %2 = sub i32 0, %11697  store atomic i32 %2, ptr %p monotonic, align 41698  ret void1699}1700 1701define void @neg_64(ptr %p) {1702; X64-LABEL: neg_64:1703; X64:       # %bb.0:1704; X64-NEXT:    negq (%rdi)1705; X64-NEXT:    retq1706;1707; X32-LABEL: neg_64:1708; X32:       # %bb.0:1709; X32-NEXT:    pushl %ebp1710; X32-NEXT:    .cfi_def_cfa_offset 81711; X32-NEXT:    .cfi_offset %ebp, -81712; X32-NEXT:    movl %esp, %ebp1713; X32-NEXT:    .cfi_def_cfa_register %ebp1714; X32-NEXT:    andl $-8, %esp1715; X32-NEXT:    subl $16, %esp1716; X32-NEXT:    movl 8(%ebp), %eax1717; X32-NEXT:    fildll (%eax)1718; X32-NEXT:    fistpll {{[0-9]+}}(%esp)1719; X32-NEXT:    xorl %ecx, %ecx1720; X32-NEXT:    xorl %edx, %edx1721; X32-NEXT:    subl {{[0-9]+}}(%esp), %edx1722; X32-NEXT:    sbbl {{[0-9]+}}(%esp), %ecx1723; X32-NEXT:    movl %edx, (%esp)1724; X32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)1725; X32-NEXT:    fildll (%esp)1726; X32-NEXT:    fistpll (%eax)1727; X32-NEXT:    movl %ebp, %esp1728; X32-NEXT:    popl %ebp1729; X32-NEXT:    .cfi_def_cfa %esp, 41730; X32-NEXT:    retl1731;   We do neg check X86-32 as it canneg do 'negq'.1732  %1 = load atomic i64, ptr %p acquire, align 81733  %2 = sub i64 0, %11734  store atomic i64 %2, ptr %p release, align 81735  ret void1736}1737 1738define void @neg_32_seq_cst(ptr %p) {1739; X64-LABEL: neg_32_seq_cst:1740; X64:       # %bb.0:1741; X64-NEXT:    movl (%rdi), %eax1742; X64-NEXT:    negl %eax1743; X64-NEXT:    xchgl %eax, (%rdi)1744; X64-NEXT:    retq1745;1746; X32-LABEL: neg_32_seq_cst:1747; X32:       # %bb.0:1748; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax1749; X32-NEXT:    movl (%eax), %ecx1750; X32-NEXT:    negl %ecx1751; X32-NEXT:    xchgl %ecx, (%eax)1752; X32-NEXT:    retl1753  %1 = load atomic i32, ptr %p monotonic, align 41754  %2 = sub i32 0, %11755  store atomic i32 %2, ptr %p seq_cst, align 41756  ret void1757}1758 1759