Open
Description
Given this code:
bool diffSignBit(int x, int y) {
return x < 0 && y >= 0 || x >= 0 && y < 0;
}
Output with -O3
:
define dso_local noundef zeroext i1 @diffSignBit(int, int)(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
%cmp = icmp slt i32 %x, 0
%cmp1 = icmp sgt i32 %y, -1
%or.cond = and i1 %cmp, %cmp1
br i1 %or.cond, label %lor.end, label %lor.rhs
lor.rhs:
%cmp2 = icmp sgt i32 %x, -1
%cmp3 = icmp slt i32 %y, 0
%0 = and i1 %cmp2, %cmp3
br label %lor.end
lor.end:
%1 = phi i1 [ %0, %lor.rhs ], [ true, %entry ]
ret i1 %1
}
If it is written as the equivalent of !sameSignBit(x, y)
,
bool diffSignBit(int x, int y) {
return !(x >= 0 && y >= 0 || x < 0 && y < 0);
}
... we get the desired output:
define dso_local noundef zeroext i1 @diffSignBit(int, int)(i32 noundef %x, i32 noundef %y) local_unnamed_addr {
entry:
%0 = xor i32 %y, %x
%lnot = icmp slt i32 %0, 0
ret i1 %lnot
}
See:
https://compiler-explorer.com/z/vWv38bGzT
https://alive2.llvm.org/ce/z/VWL1FE