; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -o - %s -mtriple=x86_64-- | FileCheck %s ; Example of a decref operation with "immortal" objects. ; void decref(long* refcount) { ; long count = *refcount; ; if (count == 1) { free_object() } ; else if (count > 1) { *refcount = count - 1; } ; else { /* immortal */ } ; } ; Resulting assembly should share flags from single CMP instruction for both ; conditions! define void @decref(ptr %p) { ; CHECK-LABEL: decref: ; CHECK: # %bb.0: ; CHECK-NEXT: movl (%rdi), %eax ; CHECK-NEXT: cmpl $1, %eax ; CHECK-NEXT: jne .LBB0_2 ; CHECK-NEXT: # %bb.1: # %bb_free ; CHECK-NEXT: pushq %rax ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: callq free_object@PLT ; CHECK-NEXT: addq $8, %rsp ; CHECK-NEXT: .cfi_def_cfa_offset 8 ; CHECK-NEXT: .LBB0_4: # %end ; CHECK-NEXT: retq ; CHECK-NEXT: .LBB0_2: # %bb2 ; CHECK-NEXT: jle .LBB0_4 ; CHECK-NEXT: # %bb.3: # %bb_dec ; CHECK-NEXT: decl %eax ; CHECK-NEXT: movl %eax, (%rdi) ; CHECK-NEXT: retq %count = load i32, ptr %p, align 4 %cmp0 = icmp eq i32 %count, 1 br i1 %cmp0, label %bb_free, label %bb2 bb2: %cmp1 = icmp sgt i32 %count, 1 br i1 %cmp1, label %bb_dec, label %end bb_dec: %dec = add nsw i32 %count, -1 store i32 %dec, ptr %p, align 4 br label %end bb_free: call void @free_object() br label %end end: ret void } declare void @free_object() ; Check TEST instruction would not be combined with CMP. define i1 @pr155586(i8 %0) { ; CHECK-LABEL: pr155586: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cmpb $1, %dil ; CHECK-NEXT: setne %cl ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: sete %al ; CHECK-NEXT: andb %cl, %al ; CHECK-NEXT: retq entry: %cmp88.not = icmp eq i8 %0, 1 %1 = and i8 %0, 1 %tobool161.not = icmp eq i8 %1, 0 %common.ret.op = select i1 %cmp88.not, i1 false, i1 %tobool161.not ret i1 %common.ret.op } ; Check TEST8rr instruction would not be combined with TEST8ri. define i32 @pr155828() { ; CHECK-LABEL: pr155828: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: .p2align 4 ; CHECK-NEXT: .LBB2_1: # %func_188.exit.i.i ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: movl %eax, %ecx ; CHECK-NEXT: movl $1, %eax ; CHECK-NEXT: testb $1, %cl ; CHECK-NEXT: jne .LBB2_1 ; CHECK-NEXT: # %bb.2: # %if.else.i.i.i ; CHECK-NEXT: xorl %eax, %eax ; CHECK-NEXT: testb %cl, %cl ; CHECK-NEXT: setg %al ; CHECK-NEXT: retq entry: br label %func_188.exit.i.i func_188.exit.i.i: ; preds = %func_188.exit.i.i, %entry %or659.i167180.i.i = phi i32 [ 0, %entry ], [ 1, %func_188.exit.i.i ] %conv48.i.i = trunc i32 %or659.i167180.i.i to i8 %and.i.i.i = and i32 %or659.i167180.i.i, 1 %tobool80.not.i.i.i = icmp eq i32 %and.i.i.i, 0 br i1 %tobool80.not.i.i.i, label %if.else.i.i.i, label %func_188.exit.i.i if.else.i.i.i: ; preds = %func_188.exit.i.i %cmp183.i.i.i = icmp sgt i8 %conv48.i.i, 0 %ext = zext i1 %cmp183.i.i.i to i32 ret i32 %ext }