Skip to content

Missed combination of addition carry flag and conditional jump #62696

@chfast

Description

@chfast

If we have a conditional branch on overflow/carry flag and this condition is merged with some other conditional branch with or i1 then the codegen is not able to use the carry flag in the branch instruction directly (it will use temporary register to store the carry with setcc).

void bad(unsigned x, unsigned y, unsigned z, unsigned* sink)
{
    unsigned s = y + z;
    _Bool ov = s < y;

    if (x || ov) 
        return;
    
    *sink = s;
}

void good(unsigned x, unsigned y, unsigned z, unsigned* sink)
{
    if (x)
        return;

    unsigned s = y + z;
    _Bool ov = s < y;

    if (ov)
        return;
    
    *sink = s;
}
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define dso_local void @bad(i32 noundef %0, i32 noundef %1, i32 noundef %2, ptr nocapture noundef writeonly %3) local_unnamed_addr #0 {
  %5 = add i32 %2, %1
  %6 = icmp ne i32 %0, 0
  %7 = icmp ult i32 %5, %1
  %8 = or i1 %6, %7
  br i1 %8, label %10, label %9

9:                                                ; preds = %4
  store i32 %5, ptr %3, align 4
  br label %10

10:                                               ; preds = %4, %9
  ret void
}

define dso_local void @good(i32 noundef %0, i32 noundef %1, i32 noundef %2, ptr nocapture noundef writeonly %3) local_unnamed_addr #0 {
  %5 = icmp eq i32 %0, 0
  br i1 %5, label %6, label %10

6:                                                ; preds = %4
  %7 = add i32 %2, %1
  %8 = icmp ult i32 %7, %1
  br i1 %8, label %10, label %9

9:                                                ; preds = %6
  store i32 %7, ptr %3, align 4
  br label %10

10:                                               ; preds = %9, %6, %4
  ret void
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
bad:                                    # @bad
        add     esi, edx
        setb    al
        test    edi, edi
        jne     .LBB0_3
        test    al, al
        jne     .LBB0_3
        mov     dword ptr [rcx], esi
.LBB0_3:
        ret
good:                                   # @good
        test    edi, edi
        je      .LBB1_1
.LBB1_3:
        ret
.LBB1_1:
        add     edx, esi
        jb      .LBB1_3
        mov     dword ptr [rcx], edx
        ret

https://godbolt.org/z/o7rMnhWcG

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions