-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Open
Description
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