Skip to content

Missed optimizations on code that compares integer sign bits #137114

Open
@MagentaTreehouse

Description

@MagentaTreehouse

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions