brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.0 KiB · f3741dc Raw
374 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i386-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK323; RUN: llc -mtriple=x86_64-linux-gnu -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK644 5; The peephole optimizer can elide some physical register copies such as6; EFLAGS. Make sure the flags are used directly, instead of needlessly using7; saving and restoring specific conditions.8 9@L = external dso_local global i3210@M = external dso_local global i811 12declare i32 @bar(i64)13 14define i1 @plus_one() nounwind {15; CHECK32-LABEL: plus_one:16; CHECK32:       # %bb.0: # %entry17; CHECK32-NEXT:    movzbl M, %eax18; CHECK32-NEXT:    incl L19; CHECK32-NEXT:    jne .LBB0_220; CHECK32-NEXT:  # %bb.1: # %entry21; CHECK32-NEXT:    andb $8, %al22; CHECK32-NEXT:    je .LBB0_223; CHECK32-NEXT:  # %bb.3: # %exit224; CHECK32-NEXT:    xorl %eax, %eax25; CHECK32-NEXT:    retl26; CHECK32-NEXT:  .LBB0_2: # %exit27; CHECK32-NEXT:    movb $1, %al28; CHECK32-NEXT:    retl29;30; CHECK64-LABEL: plus_one:31; CHECK64:       # %bb.0: # %entry32; CHECK64-NEXT:    movzbl M(%rip), %eax33; CHECK64-NEXT:    incl L(%rip)34; CHECK64-NEXT:    jne .LBB0_235; CHECK64-NEXT:  # %bb.1: # %entry36; CHECK64-NEXT:    andb $8, %al37; CHECK64-NEXT:    je .LBB0_238; CHECK64-NEXT:  # %bb.3: # %exit239; CHECK64-NEXT:    xorl %eax, %eax40; CHECK64-NEXT:    retq41; CHECK64-NEXT:  .LBB0_2: # %exit42; CHECK64-NEXT:    movb $1, %al43; CHECK64-NEXT:    retq44entry:45  %loaded_L = load i32, ptr @L46  %val = add nsw i32 %loaded_L, 1 ; N.B. will emit inc.47  store i32 %val, ptr @L48  %loaded_M = load i8, ptr @M49  %masked = and i8 %loaded_M, 850  %M_is_true = icmp ne i8 %masked, 051  %L_is_false = icmp eq i32 %val, 052  %cond = and i1 %L_is_false, %M_is_true53  br i1 %cond, label %exit2, label %exit54 55exit:56  ret i1 true57 58exit2:59  ret i1 false60}61 62define i1 @plus_forty_two() nounwind {63; CHECK32-LABEL: plus_forty_two:64; CHECK32:       # %bb.0: # %entry65; CHECK32-NEXT:    movzbl M, %eax66; CHECK32-NEXT:    addl $42, L67; CHECK32-NEXT:    jne .LBB1_268; CHECK32-NEXT:  # %bb.1: # %entry69; CHECK32-NEXT:    andb $8, %al70; CHECK32-NEXT:    je .LBB1_271; CHECK32-NEXT:  # %bb.3: # %exit272; CHECK32-NEXT:    xorl %eax, %eax73; CHECK32-NEXT:    retl74; CHECK32-NEXT:  .LBB1_2: # %exit75; CHECK32-NEXT:    movb $1, %al76; CHECK32-NEXT:    retl77;78; CHECK64-LABEL: plus_forty_two:79; CHECK64:       # %bb.0: # %entry80; CHECK64-NEXT:    movzbl M(%rip), %eax81; CHECK64-NEXT:    addl $42, L(%rip)82; CHECK64-NEXT:    jne .LBB1_283; CHECK64-NEXT:  # %bb.1: # %entry84; CHECK64-NEXT:    andb $8, %al85; CHECK64-NEXT:    je .LBB1_286; CHECK64-NEXT:  # %bb.3: # %exit287; CHECK64-NEXT:    xorl %eax, %eax88; CHECK64-NEXT:    retq89; CHECK64-NEXT:  .LBB1_2: # %exit90; CHECK64-NEXT:    movb $1, %al91; CHECK64-NEXT:    retq92entry:93  %loaded_L = load i32, ptr @L94  %val = add nsw i32 %loaded_L, 42 ; N.B. won't emit inc.95  store i32 %val, ptr @L96  %loaded_M = load i8, ptr @M97  %masked = and i8 %loaded_M, 898  %M_is_true = icmp ne i8 %masked, 099  %L_is_false = icmp eq i32 %val, 0100  %cond = and i1 %L_is_false, %M_is_true101  br i1 %cond, label %exit2, label %exit102 103exit:104  ret i1 true105 106exit2:107  ret i1 false108}109 110define i1 @minus_one() nounwind {111; CHECK32-LABEL: minus_one:112; CHECK32:       # %bb.0: # %entry113; CHECK32-NEXT:    movzbl M, %eax114; CHECK32-NEXT:    decl L115; CHECK32-NEXT:    jne .LBB2_2116; CHECK32-NEXT:  # %bb.1: # %entry117; CHECK32-NEXT:    andb $8, %al118; CHECK32-NEXT:    je .LBB2_2119; CHECK32-NEXT:  # %bb.3: # %exit2120; CHECK32-NEXT:    xorl %eax, %eax121; CHECK32-NEXT:    retl122; CHECK32-NEXT:  .LBB2_2: # %exit123; CHECK32-NEXT:    movb $1, %al124; CHECK32-NEXT:    retl125;126; CHECK64-LABEL: minus_one:127; CHECK64:       # %bb.0: # %entry128; CHECK64-NEXT:    movzbl M(%rip), %eax129; CHECK64-NEXT:    decl L(%rip)130; CHECK64-NEXT:    jne .LBB2_2131; CHECK64-NEXT:  # %bb.1: # %entry132; CHECK64-NEXT:    andb $8, %al133; CHECK64-NEXT:    je .LBB2_2134; CHECK64-NEXT:  # %bb.3: # %exit2135; CHECK64-NEXT:    xorl %eax, %eax136; CHECK64-NEXT:    retq137; CHECK64-NEXT:  .LBB2_2: # %exit138; CHECK64-NEXT:    movb $1, %al139; CHECK64-NEXT:    retq140entry:141  %loaded_L = load i32, ptr @L142  %val = add nsw i32 %loaded_L, -1 ; N.B. will emit dec.143  store i32 %val, ptr @L144  %loaded_M = load i8, ptr @M145  %masked = and i8 %loaded_M, 8146  %M_is_true = icmp ne i8 %masked, 0147  %L_is_false = icmp eq i32 %val, 0148  %cond = and i1 %L_is_false, %M_is_true149  br i1 %cond, label %exit2, label %exit150 151exit:152  ret i1 true153 154exit2:155  ret i1 false156}157 158define i1 @minus_forty_two() nounwind {159; CHECK32-LABEL: minus_forty_two:160; CHECK32:       # %bb.0: # %entry161; CHECK32-NEXT:    movzbl M, %eax162; CHECK32-NEXT:    addl $-42, L163; CHECK32-NEXT:    jne .LBB3_2164; CHECK32-NEXT:  # %bb.1: # %entry165; CHECK32-NEXT:    andb $8, %al166; CHECK32-NEXT:    je .LBB3_2167; CHECK32-NEXT:  # %bb.3: # %exit2168; CHECK32-NEXT:    xorl %eax, %eax169; CHECK32-NEXT:    retl170; CHECK32-NEXT:  .LBB3_2: # %exit171; CHECK32-NEXT:    movb $1, %al172; CHECK32-NEXT:    retl173;174; CHECK64-LABEL: minus_forty_two:175; CHECK64:       # %bb.0: # %entry176; CHECK64-NEXT:    movzbl M(%rip), %eax177; CHECK64-NEXT:    addl $-42, L(%rip)178; CHECK64-NEXT:    jne .LBB3_2179; CHECK64-NEXT:  # %bb.1: # %entry180; CHECK64-NEXT:    andb $8, %al181; CHECK64-NEXT:    je .LBB3_2182; CHECK64-NEXT:  # %bb.3: # %exit2183; CHECK64-NEXT:    xorl %eax, %eax184; CHECK64-NEXT:    retq185; CHECK64-NEXT:  .LBB3_2: # %exit186; CHECK64-NEXT:    movb $1, %al187; CHECK64-NEXT:    retq188entry:189  %loaded_L = load i32, ptr @L190  %val = add nsw i32 %loaded_L, -42 ; N.B. won't emit dec.191  store i32 %val, ptr @L192  %loaded_M = load i8, ptr @M193  %masked = and i8 %loaded_M, 8194  %M_is_true = icmp ne i8 %masked, 0195  %L_is_false = icmp eq i32 %val, 0196  %cond = and i1 %L_is_false, %M_is_true197  br i1 %cond, label %exit2, label %exit198 199exit:200  ret i1 true201 202exit2:203  ret i1 false204}205 206define i64 @test_intervening_call(ptr %foo, i64 %bar, i64 %baz) nounwind {207; CHECK32-LABEL: test_intervening_call:208; CHECK32:       # %bb.0: # %entry209; CHECK32-NEXT:    pushl %ebx210; CHECK32-NEXT:    pushl %esi211; CHECK32-NEXT:    pushl %eax212; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax213; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edx214; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ebx215; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ecx216; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %esi217; CHECK32-NEXT:    lock cmpxchg8b (%esi)218; CHECK32-NEXT:    setne %bl219; CHECK32-NEXT:    subl $8, %esp220; CHECK32-NEXT:    pushl %edx221; CHECK32-NEXT:    pushl %eax222; CHECK32-NEXT:    calll bar@PLT223; CHECK32-NEXT:    addl $16, %esp224; CHECK32-NEXT:    testb %bl, %bl225; CHECK32-NEXT:    jne .LBB4_3226; CHECK32-NEXT:  # %bb.1: # %t227; CHECK32-NEXT:    movl $42, %eax228; CHECK32-NEXT:    jmp .LBB4_2229; CHECK32-NEXT:  .LBB4_3: # %f230; CHECK32-NEXT:    xorl %eax, %eax231; CHECK32-NEXT:  .LBB4_2: # %t232; CHECK32-NEXT:    xorl %edx, %edx233; CHECK32-NEXT:    addl $4, %esp234; CHECK32-NEXT:    popl %esi235; CHECK32-NEXT:    popl %ebx236; CHECK32-NEXT:    retl237;238; CHECK64-LABEL: test_intervening_call:239; CHECK64:       # %bb.0: # %entry240; CHECK64-NEXT:    pushq %rbx241; CHECK64-NEXT:    movq %rsi, %rax242; CHECK64-NEXT:    lock cmpxchgq %rdx, (%rdi)243; CHECK64-NEXT:    setne %bl244; CHECK64-NEXT:    movq %rax, %rdi245; CHECK64-NEXT:    callq bar@PLT246; CHECK64-NEXT:    testb %bl, %bl247; CHECK64-NEXT:    jne .LBB4_2248; CHECK64-NEXT:  # %bb.1: # %t249; CHECK64-NEXT:    movl $42, %eax250; CHECK64-NEXT:    popq %rbx251; CHECK64-NEXT:    retq252; CHECK64-NEXT:  .LBB4_2: # %f253; CHECK64-NEXT:    xorl %eax, %eax254; CHECK64-NEXT:    popq %rbx255; CHECK64-NEXT:    retq256entry:257  ; cmpxchg sets EFLAGS, call clobbers it, then br uses EFLAGS.258  %cx = cmpxchg ptr %foo, i64 %bar, i64 %baz seq_cst seq_cst259  %v = extractvalue { i64, i1 } %cx, 0260  %p = extractvalue { i64, i1 } %cx, 1261  call i32 @bar(i64 %v)262  br i1 %p, label %t, label %f263 264t:265  ret i64 42266 267f:268  ret i64 0269}270 271define i64 @test_two_live_flags(ptr %foo0, i64 %bar0, i64 %baz0, ptr %foo1, i64 %bar1, i64 %baz1) nounwind {272; CHECK32-LABEL: test_two_live_flags:273; CHECK32:       # %bb.0: # %entry274; CHECK32-NEXT:    pushl %ebp275; CHECK32-NEXT:    pushl %ebx276; CHECK32-NEXT:    pushl %edi277; CHECK32-NEXT:    pushl %esi278; CHECK32-NEXT:    pushl %eax279; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ebp280; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edi281; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax282; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edx283; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ebx284; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ecx285; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %esi286; CHECK32-NEXT:    lock cmpxchg8b (%esi)287; CHECK32-NEXT:    sete {{[-0-9]+}}(%e{{[sb]}}p) # 1-byte Folded Spill288; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax289; CHECK32-NEXT:    movl %ebp, %edx290; CHECK32-NEXT:    movl %edi, %ecx291; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ebx292; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %esi293; CHECK32-NEXT:    lock cmpxchg8b (%esi)294; CHECK32-NEXT:    sete %al295; CHECK32-NEXT:    andb {{[-0-9]+}}(%e{{[sb]}}p), %al # 1-byte Folded Reload296; CHECK32-NEXT:    cmpb $1, %al297; CHECK32-NEXT:    jne .LBB5_3298; CHECK32-NEXT:  # %bb.1: # %t299; CHECK32-NEXT:    movl $42, %eax300; CHECK32-NEXT:    jmp .LBB5_2301; CHECK32-NEXT:  .LBB5_3: # %f302; CHECK32-NEXT:    xorl %eax, %eax303; CHECK32-NEXT:  .LBB5_2: # %t304; CHECK32-NEXT:    xorl %edx, %edx305; CHECK32-NEXT:    addl $4, %esp306; CHECK32-NEXT:    popl %esi307; CHECK32-NEXT:    popl %edi308; CHECK32-NEXT:    popl %ebx309; CHECK32-NEXT:    popl %ebp310; CHECK32-NEXT:    retl311;312; CHECK64-LABEL: test_two_live_flags:313; CHECK64:       # %bb.0: # %entry314; CHECK64-NEXT:    movq %rsi, %rax315; CHECK64-NEXT:    lock cmpxchgq %rdx, (%rdi)316; CHECK64-NEXT:    sete %dl317; CHECK64-NEXT:    movq %r8, %rax318; CHECK64-NEXT:    lock cmpxchgq %r9, (%rcx)319; CHECK64-NEXT:    sete %al320; CHECK64-NEXT:    andb %dl, %al321; CHECK64-NEXT:    cmpb $1, %al322; CHECK64-NEXT:    jne .LBB5_2323; CHECK64-NEXT:  # %bb.1: # %t324; CHECK64-NEXT:    movl $42, %eax325; CHECK64-NEXT:    retq326; CHECK64-NEXT:  .LBB5_2: # %f327; CHECK64-NEXT:    xorl %eax, %eax328; CHECK64-NEXT:    retq329entry:330  %cx0 = cmpxchg ptr %foo0, i64 %bar0, i64 %baz0 seq_cst seq_cst331  %p0 = extractvalue { i64, i1 } %cx0, 1332  %cx1 = cmpxchg ptr %foo1, i64 %bar1, i64 %baz1 seq_cst seq_cst333  %p1 = extractvalue { i64, i1 } %cx1, 1334  %flag = and i1 %p0, %p1335  br i1 %flag, label %t, label %f336 337t:338  ret i64 42339 340f:341  ret i64 0342}343 344define i1 @asm_clobbering_flags(ptr %mem) nounwind {345; CHECK32-LABEL: asm_clobbering_flags:346; CHECK32:       # %bb.0: # %entry347; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ecx348; CHECK32-NEXT:    movl (%ecx), %edx349; CHECK32-NEXT:    testl %edx, %edx350; CHECK32-NEXT:    setg %al351; CHECK32-NEXT:    #APP352; CHECK32-NEXT:    bsfl %edx, %edx353; CHECK32-NEXT:    #NO_APP354; CHECK32-NEXT:    movl %edx, (%ecx)355; CHECK32-NEXT:    retl356;357; CHECK64-LABEL: asm_clobbering_flags:358; CHECK64:       # %bb.0: # %entry359; CHECK64-NEXT:    movl (%rdi), %ecx360; CHECK64-NEXT:    testl %ecx, %ecx361; CHECK64-NEXT:    setg %al362; CHECK64-NEXT:    #APP363; CHECK64-NEXT:    bsfl %ecx, %ecx364; CHECK64-NEXT:    #NO_APP365; CHECK64-NEXT:    movl %ecx, (%rdi)366; CHECK64-NEXT:    retq367entry:368  %val = load i32, ptr %mem, align 4369  %cmp = icmp sgt i32 %val, 0370  %res = tail call i32 asm "bsfl $1,$0", "=r,r,~{cc},~{dirflag},~{fpsr},~{flags}"(i32 %val)371  store i32 %res, ptr %mem, align 4372  ret i1 %cmp373}374