brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · e1711cc Raw
348 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -o - -mtriple=i686-unknown-unknown %s | FileCheck %s --check-prefix=X323; RUN: llc -o - -mtriple=x86_64-unknown-unknown %s | FileCheck %s --check-prefix=X644;5; Test patterns that require preserving and restoring flags.6 7@b = common dso_local global i8 0, align 18@c = common dso_local global i32 0, align 49@a = common dso_local global i8 0, align 110@d = common dso_local global i8 0, align 111@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 112 13declare dso_local void @external(i32)14 15; A test that re-uses flags in interesting ways due to volatile accesses.16; Specifically, the first increment's flags are reused for the branch despite17; being clobbered by the second increment.18define dso_local i32 @test1() nounwind {19; X32-LABEL: test1:20; X32:       # %bb.0: # %entry21; X32-NEXT:    movzbl b, %ecx22; X32-NEXT:    movl %ecx, %eax23; X32-NEXT:    incb %al24; X32-NEXT:    movb %al, b25; X32-NEXT:    incl c26; X32-NEXT:    sete %dl27; X32-NEXT:    movb a, %ah28; X32-NEXT:    movb %ah, %ch29; X32-NEXT:    incb %ch30; X32-NEXT:    cmpb %cl, %ah31; X32-NEXT:    sete d32; X32-NEXT:    movb %ch, a33; X32-NEXT:    testb %dl, %dl34; X32-NEXT:    jne .LBB0_235; X32-NEXT:  # %bb.1: # %if.then36; X32-NEXT:    movsbl %al, %eax37; X32-NEXT:    pushl %eax38; X32-NEXT:    calll external39; X32-NEXT:    addl $4, %esp40; X32-NEXT:  .LBB0_2: # %if.end41; X32-NEXT:    xorl %eax, %eax42; X32-NEXT:    retl43;44; X64-LABEL: test1:45; X64:       # %bb.0: # %entry46; X64-NEXT:    movzbl b(%rip), %ecx47; X64-NEXT:    leal 1(%rcx), %eax48; X64-NEXT:    movb %al, b(%rip)49; X64-NEXT:    incl c(%rip)50; X64-NEXT:    sete %dl51; X64-NEXT:    movzbl a(%rip), %esi52; X64-NEXT:    leal 1(%rsi), %edi53; X64-NEXT:    cmpb %cl, %sil54; X64-NEXT:    sete d(%rip)55; X64-NEXT:    movb %dil, a(%rip)56; X64-NEXT:    testb %dl, %dl57; X64-NEXT:    jne .LBB0_258; X64-NEXT:  # %bb.1: # %if.then59; X64-NEXT:    pushq %rax60; X64-NEXT:    movsbl %al, %edi61; X64-NEXT:    callq external62; X64-NEXT:    addq $8, %rsp63; X64-NEXT:  .LBB0_2: # %if.end64; X64-NEXT:    xorl %eax, %eax65; X64-NEXT:    retq66entry:67  %bval = load i8, ptr @b68  %inc = add i8 %bval, 169  store volatile i8 %inc, ptr @b70  %cval = load volatile i32, ptr @c71  %inc1 = add nsw i32 %cval, 172  store volatile i32 %inc1, ptr @c73  %aval = load volatile i8, ptr @a74  %inc2 = add i8 %aval, 175  store volatile i8 %inc2, ptr @a76  %cmp = icmp eq i8 %aval, %bval77  %conv5 = zext i1 %cmp to i878  store i8 %conv5, ptr @d79  %tobool = icmp eq i32 %inc1, 080  br i1 %tobool, label %if.end, label %if.then81 82if.then:83  %conv6 = sext i8 %inc to i3284  call void @external(i32 %conv6)85  br label %if.end86 87if.end:88  ret i32 089}90 91; Preserve increment flags across a call.92define dso_local i32 @test2(ptr %ptr) nounwind {93; X32-LABEL: test2:94; X32:       # %bb.0: # %entry95; X32-NEXT:    pushl %ebx96; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax97; X32-NEXT:    incl (%eax)98; X32-NEXT:    setne %bl99; X32-NEXT:    pushl $42100; X32-NEXT:    calll external101; X32-NEXT:    addl $4, %esp102; X32-NEXT:    testb %bl, %bl103; X32-NEXT:    jne .LBB1_2104; X32-NEXT:  # %bb.1: # %then105; X32-NEXT:    movl $64, %eax106; X32-NEXT:    popl %ebx107; X32-NEXT:    retl108; X32-NEXT:  .LBB1_2: # %else109; X32-NEXT:    xorl %eax, %eax110; X32-NEXT:    popl %ebx111; X32-NEXT:    retl112;113; X64-LABEL: test2:114; X64:       # %bb.0: # %entry115; X64-NEXT:    pushq %rbx116; X64-NEXT:    incl (%rdi)117; X64-NEXT:    setne %bl118; X64-NEXT:    movl $42, %edi119; X64-NEXT:    callq external120; X64-NEXT:    testb %bl, %bl121; X64-NEXT:    jne .LBB1_2122; X64-NEXT:  # %bb.1: # %then123; X64-NEXT:    movl $64, %eax124; X64-NEXT:    popq %rbx125; X64-NEXT:    retq126; X64-NEXT:  .LBB1_2: # %else127; X64-NEXT:    xorl %eax, %eax128; X64-NEXT:    popq %rbx129; X64-NEXT:    retq130entry:131  %val = load i32, ptr %ptr132  %inc = add i32 %val, 1133  store i32 %inc, ptr %ptr134  %cmp = icmp eq i32 %inc, 0135  call void @external(i32 42)136  br i1 %cmp, label %then, label %else137 138then:139  ret i32 64140 141else:142  ret i32 0143}144 145declare dso_local void @external_a()146declare dso_local void @external_b()147 148; This lowers to a conditional tail call instead of a conditional branch. This149; is tricky because we can only do this from a leaf function, and so we have to150; use volatile stores similar to test1 to force the save and restore of151; a condition without calling another function. We then set up subsequent calls152; in tail position.153define dso_local void @test_tail_call(ptr %ptr) nounwind optsize {154; X32-LABEL: test_tail_call:155; X32:       # %bb.0: # %entry156; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax157; X32-NEXT:    incl (%eax)158; X32-NEXT:    setne %al159; X32-NEXT:    incb a160; X32-NEXT:    sete d161; X32-NEXT:    testb %al, %al162; X32-NEXT:    jne external_b # TAILCALL163; X32-NEXT:  # %bb.1: # %then164; X32-NEXT:    jmp external_a # TAILCALL165;166; X64-LABEL: test_tail_call:167; X64:       # %bb.0: # %entry168; X64-NEXT:    incl (%rdi)169; X64-NEXT:    setne %al170; X64-NEXT:    incb a(%rip)171; X64-NEXT:    sete d(%rip)172; X64-NEXT:    testb %al, %al173; X64-NEXT:    jne external_b # TAILCALL174; X64-NEXT:  # %bb.1: # %then175; X64-NEXT:    jmp external_a # TAILCALL176entry:177  %val = load i32, ptr %ptr178  %inc = add i32 %val, 1179  store i32 %inc, ptr %ptr180  %cmp = icmp eq i32 %inc, 0181  %aval = load volatile i8, ptr @a182  %inc2 = add i8 %aval, 1183  store volatile i8 %inc2, ptr @a184  %cmp2 = icmp eq i8 %inc2, 0185  %conv5 = zext i1 %cmp2 to i8186  store i8 %conv5, ptr @d187  br i1 %cmp, label %then, label %else188 189then:190  tail call void @external_a()191  ret void192 193else:194  tail call void @external_b()195  ret void196}197 198; Test a function that gets special select lowering into CFG with copied EFLAGS199; threaded across the CFG. This requires our EFLAGS copy rewriting to handle200; cross-block rewrites in at least some narrow cases.201define dso_local void @PR37100(i8 %arg1, i16 %arg2, i64 %arg3, i8 %arg4, ptr %ptr1, ptr %ptr2, i32 %x) nounwind {202; X32-LABEL: PR37100:203; X32:       # %bb.0: # %bb204; X32-NEXT:    pushl %ebp205; X32-NEXT:    pushl %ebx206; X32-NEXT:    pushl %edi207; X32-NEXT:    pushl %esi208; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi209; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebx210; X32-NEXT:    movl {{[0-9]+}}(%esp), %ebp211; X32-NEXT:    movb {{[0-9]+}}(%esp), %ch212; X32-NEXT:    movb {{[0-9]+}}(%esp), %cl213; X32-NEXT:    jmp .LBB3_1214; X32-NEXT:    .p2align 4215; X32-NEXT:  .LBB3_5: # %bb1216; X32-NEXT:    # in Loop: Header=BB3_1 Depth=1217; X32-NEXT:    movl %esi, %eax218; X32-NEXT:    cltd219; X32-NEXT:    idivl %edi220; X32-NEXT:  .LBB3_1: # %bb1221; X32-NEXT:    # =>This Inner Loop Header: Depth=1222; X32-NEXT:    movsbl %cl, %eax223; X32-NEXT:    movl %eax, %edx224; X32-NEXT:    sarl $31, %edx225; X32-NEXT:    cmpl %eax, {{[0-9]+}}(%esp)226; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax227; X32-NEXT:    sbbl %edx, %eax228; X32-NEXT:    setl %al229; X32-NEXT:    setl %dl230; X32-NEXT:    movzbl %dl, %edi231; X32-NEXT:    negl %edi232; X32-NEXT:    testb %al, %al233; X32-NEXT:    jne .LBB3_3234; X32-NEXT:  # %bb.2: # %bb1235; X32-NEXT:    # in Loop: Header=BB3_1 Depth=1236; X32-NEXT:    movb %ch, %cl237; X32-NEXT:  .LBB3_3: # %bb1238; X32-NEXT:    # in Loop: Header=BB3_1 Depth=1239; X32-NEXT:    movb %cl, (%ebp)240; X32-NEXT:    movl (%ebx), %edx241; X32-NEXT:    testb %al, %al242; X32-NEXT:    jne .LBB3_5243; X32-NEXT:  # %bb.4: # %bb1244; X32-NEXT:    # in Loop: Header=BB3_1 Depth=1245; X32-NEXT:    movl %edx, %edi246; X32-NEXT:    jmp .LBB3_5247;248; X64-LABEL: PR37100:249; X64:       # %bb.0: # %bb250; X64-NEXT:    movq %rdx, %r10251; X64-NEXT:    movl {{[0-9]+}}(%rsp), %esi252; X64-NEXT:    movzbl %cl, %ecx253; X64-NEXT:    .p2align 4254; X64-NEXT:  .LBB3_1: # %bb1255; X64-NEXT:    # =>This Inner Loop Header: Depth=1256; X64-NEXT:    movsbq %dil, %rax257; X64-NEXT:    xorl %r11d, %r11d258; X64-NEXT:    cmpq %rax, %r10259; X64-NEXT:    setl %r11b260; X64-NEXT:    negl %r11d261; X64-NEXT:    cmpq %rax, %r10262; X64-NEXT:    movzbl %al, %edi263; X64-NEXT:    cmovgel %ecx, %edi264; X64-NEXT:    movb %dil, (%r8)265; X64-NEXT:    cmovgel (%r9), %r11d266; X64-NEXT:    movl %esi, %eax267; X64-NEXT:    cltd268; X64-NEXT:    idivl %r11d269; X64-NEXT:    jmp .LBB3_1270bb:271  br label %bb1272 273bb1:274  %tmp = phi i8 [ %tmp8, %bb1 ], [ %arg1, %bb ]275  %tmp2 = phi i16 [ %tmp12, %bb1 ], [ %arg2, %bb ]276  %tmp3 = icmp sgt i16 %tmp2, 7277  %tmp4 = select i1 %tmp3, i16 %tmp2, i16 7278  %tmp5 = sext i8 %tmp to i64279  %tmp6 = icmp slt i64 %arg3, %tmp5280  %tmp7 = sext i1 %tmp6 to i32281  %tmp8 = select i1 %tmp6, i8 %tmp, i8 %arg4282  store volatile i8 %tmp8, ptr %ptr1283  %tmp9 = load volatile i32, ptr %ptr2284  %tmp10 = select i1 %tmp6, i32 %tmp7, i32 %tmp9285  %tmp11 = srem i32 %x, %tmp10286  %tmp12 = trunc i32 %tmp11 to i16287  br label %bb1288}289 290; Use a particular instruction pattern in order to lower to the post-RA pseudo291; used to lower SETB into an SBB pattern in order to make sure that kind of292; usage of a copied EFLAGS continues to work.293define dso_local void @PR37431(ptr %arg1, ptr %arg2, ptr %arg3, i32 %arg4, i64 %arg5) nounwind {294; X32-LABEL: PR37431:295; X32:       # %bb.0: # %entry296; X32-NEXT:    pushl %ebp297; X32-NEXT:    pushl %ebx298; X32-NEXT:    pushl %edi299; X32-NEXT:    pushl %esi300; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx301; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax302; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx303; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi304; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi305; X32-NEXT:    movl (%edi), %edi306; X32-NEXT:    movl %edi, %ebp307; X32-NEXT:    sarl $31, %ebp308; X32-NEXT:    xorl %ebx, %ebx309; X32-NEXT:    cmpl %edi, {{[0-9]+}}(%esp)310; X32-NEXT:    sbbl %ebp, %esi311; X32-NEXT:    sbbl %ebx, %ebx312; X32-NEXT:    movb %bl, (%edx)313; X32-NEXT:    cltd314; X32-NEXT:    idivl %ebx315; X32-NEXT:    movb %dl, (%ecx)316; X32-NEXT:    popl %esi317; X32-NEXT:    popl %edi318; X32-NEXT:    popl %ebx319; X32-NEXT:    popl %ebp320; X32-NEXT:    retl321;322; X64-LABEL: PR37431:323; X64:       # %bb.0: # %entry324; X64-NEXT:    movl %ecx, %eax325; X64-NEXT:    movq %rdx, %rcx326; X64-NEXT:    movslq (%rdi), %rdx327; X64-NEXT:    xorl %edi, %edi328; X64-NEXT:    cmpq %rdx, %r8329; X64-NEXT:    sbbl %edi, %edi330; X64-NEXT:    movb %dil, (%rsi)331; X64-NEXT:    cltd332; X64-NEXT:    idivl %edi333; X64-NEXT:    movb %dl, (%rcx)334; X64-NEXT:    retq335entry:336  %tmp = load i32, ptr %arg1337  %tmp1 = sext i32 %tmp to i64338  %tmp2 = icmp ugt i64 %tmp1, %arg5339  %tmp3 = zext i1 %tmp2 to i8340  %tmp4 = sub i8 0, %tmp3341  store i8 %tmp4, ptr %arg2342  %tmp5 = sext i8 %tmp4 to i32343  %tmp6 = srem i32 %arg4, %tmp5344  %tmp7 = trunc i32 %tmp6 to i8345  store i8 %tmp7, ptr %arg3346  ret void347}348