[llvm-bugs] [Bug 51671] New: (Simple)LoopUnswitch introduces branch on poison if call doesn't return

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Aug 30 03:46:31 PDT 2021


https://bugs.llvm.org/show_bug.cgi?id=51671

            Bug ID: 51671
           Summary: (Simple)LoopUnswitch introduces branch on poison if
                    call doesn't return
           Product: libraries
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Keywords: miscompilation
          Severity: normal
          Priority: P
         Component: Loop Optimizer
          Assignee: unassignedbugs at nondot.org
          Reporter: nunoplopes at sapo.pt
                CC: aeubanks at google.com, alina.sbirlea at gmail.com,
                    florian_hahn at apple.com, llvm-bugs at lists.llvm.org,
                    max.kazantsev at azul.com, nikita.ppv at gmail.com

Tests:
 - Transforms/LoopUnswitch/preserve-analyses.ll
 - Transforms/SimpleLoopUnswitch/delete-dead-blocks.ll
 - Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll


In the test below, @pci_get_device may not return. In that case, the source
function will not branch on the undef %conv56.
The target function always branches on %conv56 regardless of whether
@pci_get_device returns or not.
The fix is to freeze the condition if the code doesn't provably reach the
branch.


define void @pnp_check_irq() {
%entry:
  %conv56 = trunc i64 undef to i32
  br label %while.cond.i

%while.cond.i:
  %call.i25 = call * @pci_get_device()
  br i1 undef, label %if.then65, label %while.body.i

%if.then65:
  assume i1 0

%while.body.i:
  br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge

%if.then31.i.i:
  switch i32 %conv56, label %while.cond.i.backedge [
    i32 14, label %if.then42.i.i
    i32 15, label %if.then42.i.i
  ]

%if.then42.i.i:
  %call.i25.lcssa48 = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
  assume i1 0

%while.cond.i.backedge:
  br label %while.cond.i
}
=>
define void @pnp_check_irq() {
%entry:
  %conv56 = trunc i64 undef to i32
  %0 = icmp eq i32 %conv56, 14
  br i1 %0, label %entry.split.us, label %entry.entry.split_crit_edge

%entry.entry.split_crit_edge:
  br label %entry.split

%entry.split:
  %1 = icmp eq i32 %conv56, 15
  br i1 %1, label %entry.split.split.us, label
%entry.split.entry.split.split_crit_edge

%entry.split.split.us:
  br label %while.cond.i.us1

%while.cond.i.us1:
  %call.i25.us2 = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us-lcssa.us, label %while.body.i.us3

%if.then65.us-lcssa.us-lcssa.us:
  br label %if.then65.us-lcssa

%while.body.i.us3:
  br i1 undef, label %if.then31.i.i.us4, label %while.cond.i.backedge.us5

%if.then31.i.i.us4:
  switch i32 15, label %while.cond.i.backedge.us5 [
    i32 14, label %if.then42.i.i.us-lcssa.us-lcssa.us
    i32 15, label %if.then42.i.i.us-lcssa.us-lcssa.us
  ]

%if.then42.i.i.us-lcssa.us-lcssa.us:
  %call.i25.lcssa48.ph.ph.us = phi * [ %call.i25.us2, %if.then31.i.i.us4 ], [
%call.i25.us2, %if.then31.i.i.us4 ]
  br label %if.then42.i.i.us-lcssa

%while.cond.i.backedge.us5:
  br label %while.cond.i.us1

%entry.split.entry.split.split_crit_edge:
  br label %entry.split.split

%entry.split.split:
  br label %while.cond.i

%while.cond.i:
  %call.i25 = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us-lcssa, label %while.body.i

%if.then65.us-lcssa.us-lcssa:
  br label %if.then65.us-lcssa

%if.then65.us-lcssa:
  br label %if.then65

%while.body.i:
  br i1 undef, label %if.then31.i.i, label %while.cond.i.backedge

%if.then31.i.i:
  switch i32 %conv56, label %while.cond.i.backedge [
    i32 14, label %if.then42.i.i.us-lcssa.us-lcssa
    i32 15, label %if.then42.i.i.us-lcssa.us-lcssa
  ]

%if.then42.i.i.us-lcssa.us-lcssa:
  %call.i25.lcssa48.ph.ph = phi * [ %call.i25, %if.then31.i.i ], [ %call.i25,
%if.then31.i.i ]
  br label %if.then42.i.i.us-lcssa

%if.then42.i.i.us-lcssa:
  %call.i25.lcssa48.ph = phi * [ %call.i25.lcssa48.ph.ph,
%if.then42.i.i.us-lcssa.us-lcssa ], [ %call.i25.lcssa48.ph.ph.us,
%if.then42.i.i.us-lcssa.us-lcssa.us ]
  br label %if.then42.i.i

%while.cond.i.backedge:
  br label %while.cond.i

%entry.split.us:
  br label %while.cond.i.us

%while.cond.i.us:
  %call.i25.us = call * @pci_get_device()
  br i1 1, label %if.then65.us-lcssa.us, label %while.body.i.us

%if.then65.us-lcssa.us:
  br label %if.then65

%if.then65:
  assume i1 0

%while.body.i.us:
  br i1 undef, label %if.then31.i.i.us, label %while.cond.i.backedge.us

%if.then31.i.i.us:
  switch i32 14, label %while.cond.i.backedge.us [
    i32 14, label %if.then42.i.i.us-lcssa.us
    i32 15, label %if.then42.i.i.us-lcssa.us
  ]

%if.then42.i.i.us-lcssa.us:
  %call.i25.lcssa48.ph.us = phi * [ %call.i25.us, %if.then31.i.i.us ], [
%call.i25.us, %if.then31.i.i.us ]
  br label %if.then42.i.i

%if.then42.i.i:
  %call.i25.lcssa48 = phi * [ %call.i25.lcssa48.ph, %if.then42.i.i.us-lcssa ],
[ %call.i25.lcssa48.ph.us, %if.then42.i.i.us-lcssa.us ]
  assume i1 0

%while.cond.i.backedge.us:
  br label %while.cond.i.us
}
Transformation doesn't verify!
ERROR: Source is more defined than target

Example:

Source:
i32 %conv56 = any
* %call.i25 = poison

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 1        alloc type: 0
Block 1 >       size: 0 align: 1

Target:
i32 %conv56 = #xfffffff1 (4294967281, -15)
i1 %0 = #x0 (0)
i1 %1 = #x0 (0)
* %call.i25.us2 = poison
* %call.i25 = poison
* %call.i25.us = poison

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210830/b228a0ce/attachment.html>


More information about the llvm-bugs mailing list