Skip to content

[GVNPass] Range attribute should be handled after CSE #113997

Closed
@dtcxzyw

Description

@dtcxzyw

Reproducer: https://alive2.llvm.org/ce/z/HAnoKn

define i1 @src(i32 noundef %x) {
  %cmp1 = icmp sgt i32 %x, 0
  %ctpop1 = tail call range(i32 1, 32) i32 @llvm.ctpop.i32(i32 %x)
  %cmp2 = icmp samesign ult i32 %ctpop1, 2
  %cond = select i1 %cmp1, i1 %cmp2, i1 false
  br i1 %cond, label %if.then, label %if.else

if.else:
  %ctpop2 = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 %x)
  %res = icmp eq i32 %ctpop2, 1
  ret i1 %res

if.then:
  ret i1 false
}

define i1 @tgt(i32 noundef %x) {
  %cmp1 = icmp sgt i32 %x, 0
  %ctpop1 = tail call range(i32 1, 32) i32 @llvm.ctpop.i32(i32 %x)
  %cmp2 = icmp samesign ult i32 %ctpop1, 2
  %cond = select i1 %cmp1, i1 %cmp2, i1 false
  br i1 %cond, label %if.then, label %if.else

if.else:
  %res = icmp eq i32 %ctpop1, 1
  ret i1 %res

if.then:
  ret i1 false
}

----------------------------------------
define i1 @src(i32 noundef %x) {
#0:
  %cmp1 = icmp sgt i32 noundef %x, 0
  %ctpop1 = ctpop i32 noundef %x
  %#range_0_%ctpop1 = !range i32 %ctpop1, i32 1, i32 32
  %cmp2 = icmp samesign ult i32 %#range_0_%ctpop1, 2
  %cond = select i1 %cmp1, i1 %cmp2, i1 0
  br i1 %cond, label %if.then, label %if.else

if.else:
  %ctpop2 = ctpop i32 noundef %x
  %#range_1_%ctpop2 = !range i32 %ctpop2, i32 0, i32 33
  %res = icmp eq i32 %#range_1_%ctpop2, 1
  ret i1 %res

if.then:
  ret i1 0
}
=>
define i1 @tgt(i32 noundef %x) {
#0:
  %cmp1 = icmp sgt i32 noundef %x, 0
  %ctpop1 = ctpop i32 noundef %x
  %#range_0_%ctpop1 = !range i32 %ctpop1, i32 1, i32 32
  %cmp2 = icmp samesign ult i32 %#range_0_%ctpop1, 2
  %cond = select i1 %cmp1, i1 %cmp2, i1 0
  br i1 %cond, label %if.then, label %if.else

if.else:
  %res = icmp eq i32 %#range_0_%ctpop1, 1
  ret i1 %res

if.then:
  ret i1 0
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
i32 noundef %x = #x00000000 (0)

Source:
i1 %cmp1 = #x0 (0)
i32 %ctpop1 = #x00000000 (0)
i32 %#range_0_%ctpop1 = poison
i1 %cmp2 = poison
i1 %cond = #x0 (0)
  >> Jump to %if.else
i32 %ctpop2 = #x00000000 (0)
i32 %#range_1_%ctpop2 = #x00000000 (0)
i1 %res = #x0 (0)

Target:
i1 %cmp1 = #x0 (0)
i32 %ctpop1 = #x00000000 (0)
i32 %#range_0_%ctpop1 = poison
i1 %cmp2 = poison
i1 %cond = #x0 (0)
  >> Jump to %if.else
i1 %res = poison
Source value: #x0 (0)
Target value: poison

Reported by @pranavk. See #100899 (comment).

Metadata

Metadata

Assignees

Labels

llvm:GVNGVN and NewGVN stages (Global value numbering)miscompilation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions