[llvm-bugs] [Bug 29127] New: load/store address constant offsets with negative register values

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Aug 24 14:14:20 PDT 2016


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

            Bug ID: 29127
           Summary: load/store address constant offsets with negative
                    register values
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: WebAssembly
          Assignee: unassignedbugs at nondot.org
          Reporter: dschuff at google.com
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

Created attachment 17038
  --> https://llvm.org/bugs/attachment.cgi?id=17038&action=edit
input IR

The following C code:

int args[32];

int main() {
  int i;
  #pragma clang loop unroll(disable)
  for (i=0;i<32;i++) args[i]=1;
  return 0;
}

compiles with -O to the following IR:
@args = hidden local_unnamed_addr global [32 x i32] zeroinitializer, align 16
...
for.body:                                         ; preds = %for.body, %entry
  %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %arrayidx = getelementptr inbounds [32 x i32], [32 x i32]* @args, i32 0, i32
%i.04
  store i32 1, i32* %arrayidx, align 4, !tbaa !1


When the backend runs loop strength reduction, it becomes this:

for.body:                                         ; preds = %for.body, %entry
  %lsr.iv = phi i32 [ %lsr.iv.next, %for.body ], [ -128, %entry ]
  %lsr.iv1 = inttoptr i32 %lsr.iv to i32*
  %uglygep = getelementptr i8, i8* bitcast ([32 x i32]* @args to i8*), i32
%lsr.iv
  %uglygep2 = bitcast i8* %uglygep to i32*
  %scevgep = getelementptr i32, i32* %uglygep2, i32 32
  store i32 1, i32* %scevgep, align 4, !tbaa !1

After SelectionDAGBuilder we get

%vreg0 = -128
...
store(1, add( add(GlobalAddr<@args>, %vreg0), 128))

Which the DAGcombiner reduces to
%vreg0 = -128
store(1, add(%vreg0, Wrapper(TGlobalAddr<@args>+128)))

and then selects to
# BB#0:                                 # %entry
    i32.const    $0=, -128
.LBB0_1:                                # %for.body
                                        # =>This Inner Loop Header: Depth=1
    loop                            # label0:
    i32.const    $push4=, 1
    i32.store    $drop=, args+128($0), $pop4

The problem is that the address calculation:
@args+128 + $0 (where $0 starts at -128) 
is unsigned, so it overflows.

It seems there are a couple places we could prevent this:
One is in the LSR/SCEV cost modeling/formula selection. LSR chooses an address
formula it prints as  
@args + 128 + reg({-128,+,4}<nuw><nsw><%for.body>)

isLegalAddressingMode seems like it might be a way to disallow this, but it
doesn't quite cover it because GV + offset + reg is legal and we want to allow
it (currently we allow it if offset >= 0); the problem here is that LSR has
chosen a negative value range for the register.

This can be disabled by e.g. hacking Cost::RateFormula
(LoopStrengthReduce.cpp:1130) to cause a SCEV BaseReg to "Lose" (i.e. not be
selected) if it has a known negative value (or do something equivalent to
that). Changing the cost model or selection this way might entail adding
something to TargetTransformInfo alongside isLegalAddressingMode (i.e. if the
target address calculation is unsigned or something like that).
That selection is sort of the deepest cause of the problem.


Another way might be to prevent one of the other events down the chain. e.g.
the dag combiner folds the add(GlobalAddr<@args>, %vreg0) but that seems legit,
and isel folds the GA expression into the constant offset which it seems like
we'd want, and there are some subtleties around the changes we made to how the
nsw/nuw flags are treated that I'm not sure I fully understand yet, so I don't
yet see an obvious way to fix this there without disallowing other things we do
want to allow. I'm also not clear whether there are other potential sources of
similar issues, i.e. a register with a negative value combined with a constant
offset.

-- 
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/20160824/acb7680c/attachment.html>


More information about the llvm-bugs mailing list