Skip to content

[SCCP][IPSCCP] Miscompilation: unsound fold of recursive self-call with non-unique fixed point #158082

@zitongzhoueric

Description

@zitongzhoueric

To reproduce: https://alive2.llvm.org/ce/z/qruVRC
The function foo admits multiple fixpoints (0,1) but is folded into ret i32 1. It won't return in either case, but I'm not sure the fold can be considered correct.

; Function Attrs: nofree nosync nounwind memory(none) uwtable 
define dso_local range(i32 0, 2) i32 @foo(i32 noundef %a) local_unnamed_addr {
entry:
  %call = call i32 @foo(i32 noundef 1)
  %cmp.not = icmp eq i32 %call, 0
  %spec.select = select i1 %cmp.not, i32 0, i32 1
  %cmp1 = icmp slt i32 %a, 0
  %x.1 = select i1 %cmp1, i32 1, i32 %spec.select
  ret i32 %x.1
}
=>
define dso_local range(i32 0, 2) i32 @foo(i32 noundef %a) local_unnamed_addr {
entry:
  %call = call i32 @foo(i32 noundef 1)
  %cmp1 = icmp slt i32 %a, 0
  ret i32 1
}
----------------------------------------
declare i32 @foo(noundef i32)

define i32 @foo(i32 noundef %a) {
entry:
  %call = call i32 @foo(noundef i32 1)
  %#range_0_%call = !range i32 %call, i32 0, i32 2
  %#range_1_%#range_0_%call = !range i32 %#range_0_%call, i32 0, i32 2
  %cmp.not = icmp eq i32 %#range_1_%#range_0_%call, 0
  %spec.select = select i1 %cmp.not, i32 0, i32 1
  %cmp1 = icmp slt i32 noundef %a, 0
  %x.1 = select i1 %cmp1, i32 1, i32 %spec.select
  %#range_2_%x.1 = !range i32 %x.1, i32 0, i32 2
  ret i32 %#range_2_%x.1
}
=>
declare i32 @foo(noundef i32)

define i32 @foo(i32 noundef %a) {
entry:
  %call = call i32 @foo(noundef i32 1)
  %#range_2_1 = !range i32 1, i32 0, i32 2
  ret i32 %#range_2_1
}
Transformation doesn't verify!

ERROR: Value mismatch

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

Source:
i32 %call = #x00000000 (0)
i32 %#range_0_%call = #x00000000 (0)
i32 %#range_1_%#range_0_%call = #x00000000 (0)
i1 %cmp.not = #x1 (1)
i32 %spec.select = #x00000000 (0)
i1 %cmp1 = #x0 (0)
i32 %x.1 = #x00000000 (0)
i32 %#range_2_%x.1 = #x00000000 (0)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >	size: 0	align: 1	alloc type: 0	alive: false	address: #x0
Block 1 >	size: 0	align: 8	alloc type: 0	alive: true	address: #x8

Target:
i32 %call = #x00000000 (0)
i32 %#range_2_1 = #x00000001 (1)

TARGET MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >	size: 0	align: 1	alloc type: 0	alive: false	address: #x0
Block 1 >	size: 0	align: 8	alloc type: 0	alive: true	address: #x8
Source value: #x00000000 (0)
Target value: #x00000001 (1)

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    llvm:optimizationsmiscompilationquestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions