Skip to content

constraint elimination should understand the (x<0)||(y<0) => (x|y)<0 canonicalization #118114

Open
@regehr

Description

@regehr

here's a function:

extern void side_effect(void);

void f(int v1, int v2) {
  if (v1 < 0) return;
  if (v2 < 0) return;
  if (v2 > -5) return;
  side_effect();
}

at present, we're not optimizing this away. the IR is:

define void @f(i32 noundef %v1, i32 noundef %v2) {
entry:
  %0 = or i32 %v2, %v1
  %or.cond = icmp slt i32 %0, 0
  %cmp4 = icmp sgt i32 %v2, -5
  %or.cond7 = or i1 %cmp4, %or.cond
  br i1 %or.cond7, label %return, label %if.end6

if.end6:                                          ; preds = %entry
  tail call void @side_effect() #2
  br label %return

return:                                           ; preds = %entry, %if.end6
  ret void
}

constraint elimination is correctly learning that !(%0 < 0) but I guess we need a little recognizer for the (x<0)||(y<0) => (x|y)<0 canonicalization

Processing condition to simplify:   %or.cond = icmp slt i32 %0, 0
Checking   %or.cond = icmp slt i32 %0, 0
   failed to decompose condition
Adding 'icmp sle i32 %v2, -5'
  constraint: %v2 <= -5

Checking   %or.cond = icmp slt i32 %0, 0
   failed to decompose condition
Processing condition to simplify:   %cmp4 = icmp sgt i32 %v2, -5
Checking   %cmp4 = icmp sgt i32 %v2, -5
---
%v2 <= -5
sat
---
-1 * %v2 <= 4
sat
Adding 'icmp sge i32 %0, 0'
  constraint: -1 * %0 <= 0

Checking   %cmp4 = icmp sgt i32 %v2, -5
---
-1 * %0 <= 0
%v2 <= -5
sat
---
-1 * %0 <= 0
-1 * %v2 <= 4
sat
Processing fact to add to the system: icmp sle i32 %v2, -5
Adding 'icmp sle i32 %v2, -5'
  constraint: %v2 <= -5

Top of stack : 3 4
CB: 3 4
Processing fact to add to the system: icmp sge i32 %0, 0
Adding 'icmp sge i32 %0, 0'
  constraint: -1 * %0 <= 0

Adding 'icmp uge i32 %0, 0'
  constraint: -1 * %0 <= 0

cc @fhahn @dtcxzyw

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions