Skip to content

InstCombine gets stuck when sinking negation #96012

Closed
@dtcxzyw

Description

@dtcxzyw

Minimal reproducer (It looks over-reduced): https://godbolt.org/z/9zj5K8seP

; opt -passes=instcombine test.ll -S -debug
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"

define i32 @func_112() {
entry:
  br label %for.cond

for.cond:                                         ; preds = %for.cond, %entry
  %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
  %conv5 = trunc i32 %l_139.0 to i8
  %call6 = sub i8 0, %conv5
  %conv7 = zext i8 %call6 to i32
  %0 = shl nuw i32 %conv7, 24
  br label %for.cond
}
INSTCOMBINE ITERATION #1 on func_112
ADD:   br label %for.cond
ADD:   %0 = shl nuw i32 %conv7, 24
ADD:   %conv7 = zext i8 %call6 to i32
ADD:   %call6 = sub i8 0, %conv5
ADD:   %conv5 = trunc i32 %l_139.0 to i8
ADD:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
ADD:   br label %for.cond
IC: Visiting:   br label %for.cond
IC: Visiting:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
IC: Visiting:   %conv5 = trunc i32 %l_139.0 to i8
IC: Visiting:   %call6 = sub i8 0, %conv5
Negator: attempting to sink negation into   %conv5 = trunc i32 %l_139.0 to i8
Negator: successfully sunk negation into   %conv5 = trunc i32 %l_139.0 to i8
         NEW:   %conv5.neg = trunc i32 %l_139.0.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg = mul i32 %conv7, -16777216
ADD DEFERRED:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
IC: Old =   %call6 = sub i8 0, %conv5
    New =   <badref> = add i8 %conv5.neg, 0
ADD:   %call6 = add i8 %conv5.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5
ADD DEFERRED:   %conv5 = trunc i32 %l_139.0 to i8
IC: ERASE   %conv5 = trunc i32 %l_139.0 to i8
ADD DEFERRED:   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
IC: ERASE   %l_139.0 = phi i32 [ 1, %entry ], [ %0, %for.cond ]
ADD DEFERRED:   %0 = shl nuw i32 %conv7, 24
IC: ERASE   %0 = shl nuw i32 %conv7, 24
ADD DEFERRED:   %conv7 = zext i8 %call6 to i32
ADD:   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD:   %.neg = mul i32 %conv7, -16777216
IC: Visiting:   %.neg = mul i32 %conv7, -16777216
Negator: attempting to sink negation into   %conv7 = zext i8 %call6 to i32
Negator: failed to sink negation into   %conv7 = zext i8 %call6 to i32
ADD DEFERRED:   %call6.neg = sub i8 0, %call6
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
IC: Old =   %.neg = mul i32 %conv7, -16777216
    New =   <badref> = shl i32 %call6.neg.z, 24
ADD:   %.neg = shl i32 %call6.neg.z, 24
IC: ERASE   %0 = mul i32 %conv7, -16777216
ADD DEFERRED:   %conv7 = zext i8 %call6 to i32
IC: ERASE   %conv7 = zext i8 %call6 to i32
ADD DEFERRED:   %call6 = add i8 %conv5.neg, 0
ADD:   %call6.neg.z = zext i8 %call6.neg to i32
ADD:   %call6.neg = sub i8 0, %call6
IC: Visiting:   %call6.neg = sub i8 0, %call6
IC: Old =   %call6.neg = sub i8 0, %call6
    New =   <badref> = sub i8 0, %conv5.neg
ADD:   %call6.neg = sub i8 0, %conv5.neg
IC: ERASE   %0 = sub i8 0, %call6
ADD DEFERRED:   %call6 = add i8 %conv5.neg, 0
IC: ERASE   %call6 = add i8 %conv5.neg, 0
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD DEFERRED:   %call6.neg = sub i8 0, %conv5.neg
IC: Visiting:   %call6.neg = sub i8 0, %conv5.neg
Negator: attempting to sink negation into   %conv5.neg = trunc i32 %l_139.0.neg to i8
Negator: successfully sunk negation into   %conv5.neg = trunc i32 %l_139.0.neg to i8
         NEW:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg.neg = mul i32 %call6.neg.z, -16777216
ADD DEFERRED:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
IC: Old =   %call6.neg = sub i8 0, %conv5.neg
    New =   <badref> = add i8 %conv5.neg.neg, 0
ADD:   %call6.neg = add i8 %conv5.neg.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5.neg
ADD DEFERRED:   %conv5.neg = trunc i32 %l_139.0.neg to i8
IC: ERASE   %conv5.neg = trunc i32 %l_139.0.neg to i8
ADD DEFERRED:   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
IC: ERASE   %l_139.0.neg = phi i32 [ -1, %entry ], [ %.neg, %for.cond ]
ADD DEFERRED:   %.neg = shl i32 %call6.neg.z, 24
IC: ERASE   %.neg = shl i32 %call6.neg.z, 24
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
ADD:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD:   %.neg.neg = mul i32 %call6.neg.z, -16777216
IC: Visiting:   %.neg.neg = mul i32 %call6.neg.z, -16777216
Negator: attempting to sink negation into   %call6.neg.z = zext i8 %call6.neg to i32
Negator: failed to sink negation into   %call6.neg.z = zext i8 %call6.neg to i32
ADD DEFERRED:   %call6.neg.neg = sub i8 0, %call6.neg
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
IC: Old =   %.neg.neg = mul i32 %call6.neg.z, -16777216
    New =   <badref> = shl i32 %call6.neg.neg.z, 24
ADD:   %.neg.neg = shl i32 %call6.neg.neg.z, 24
IC: ERASE   %0 = mul i32 %call6.neg.z, -16777216
ADD DEFERRED:   %call6.neg.z = zext i8 %call6.neg to i32
IC: ERASE   %call6.neg.z = zext i8 %call6.neg to i32
ADD DEFERRED:   %call6.neg = add i8 %conv5.neg.neg, 0
ADD:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD:   %call6.neg.neg = sub i8 0, %call6.neg
IC: Visiting:   %call6.neg.neg = sub i8 0, %call6.neg
IC: Old =   %call6.neg.neg = sub i8 0, %call6.neg
    New =   <badref> = sub i8 0, %conv5.neg.neg
ADD:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
IC: ERASE   %0 = sub i8 0, %call6.neg
ADD DEFERRED:   %call6.neg = add i8 %conv5.neg.neg, 0
IC: ERASE   %call6.neg = add i8 %conv5.neg.neg, 0
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD DEFERRED:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
IC: Visiting:   %call6.neg.neg = sub i8 0, %conv5.neg.neg
Negator: attempting to sink negation into   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
Negator: successfully sunk negation into   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
         NEW:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
Negator: Propagating 3 instrs to InstCombine
ADD DEFERRED:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
ADD DEFERRED:   %l_139.0.neg.neg.neg = phi i32 [ -1, %entry ], [ %.neg.neg.neg, %for.cond ]
ADD DEFERRED:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
IC: Old =   %call6.neg.neg = sub i8 0, %conv5.neg.neg
    New =   <badref> = add i8 %conv5.neg.neg.neg, 0
ADD:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
IC: ERASE   %0 = sub i8 0, %conv5.neg.neg
ADD DEFERRED:   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
IC: ERASE   %conv5.neg.neg = trunc i32 %l_139.0.neg.neg to i8
ADD DEFERRED:   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
IC: ERASE   %l_139.0.neg.neg = phi i32 [ 1, %entry ], [ %.neg.neg, %for.cond ]
ADD DEFERRED:   %.neg.neg = shl i32 %call6.neg.neg.z, 24
IC: ERASE   %.neg.neg = shl i32 %call6.neg.neg.z, 24
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
ADD:   %l_139.0.neg.neg.neg = phi i32 [ -1, %entry ], [ %.neg.neg.neg, %for.cond ]
ADD:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
IC: Visiting:   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
Negator: attempting to sink negation into   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
Negator: failed to sink negation into   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD DEFERRED:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
ADD DEFERRED:   %call6.neg.neg.neg.z = zext i8 %call6.neg.neg.neg to i32
IC: Old =   %.neg.neg.neg = mul i32 %call6.neg.neg.z, -16777216
    New =   <badref> = shl i32 %call6.neg.neg.neg.z, 24
ADD:   %.neg.neg.neg = shl i32 %call6.neg.neg.neg.z, 24
IC: ERASE   %0 = mul i32 %call6.neg.neg.z, -16777216
ADD DEFERRED:   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
IC: ERASE   %call6.neg.neg.z = zext i8 %call6.neg.neg to i32
ADD DEFERRED:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
ADD:   %call6.neg.neg.neg.z = zext i8 %call6.neg.neg.neg to i32
ADD:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
IC: Visiting:   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
IC: Old =   %call6.neg.neg.neg = sub i8 0, %call6.neg.neg
    New =   <badref> = sub i8 0, %conv5.neg.neg.neg
ADD:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
IC: ERASE   %0 = sub i8 0, %call6.neg.neg
ADD DEFERRED:   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
IC: ERASE   %call6.neg.neg = add i8 %conv5.neg.neg.neg, 0
ADD DEFERRED:   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
ADD DEFERRED:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
IC: Visiting:   %call6.neg.neg.neg = sub i8 0, %conv5.neg.neg.neg
Negator: attempting to sink negation into   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
Negator: successfully sunk negation into   %conv5.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg to i8
         NEW:   %conv5.neg.neg.neg.neg = trunc i32 %l_139.0.neg.neg.neg.neg to i8
...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions