This is an archive of the discontinued LLVM Phabricator instance.

[PR27390] [CodeGen] Reject indexed loads in CombinerDAG.
ClosedPublic

Authored by koriakin on Apr 17 2016, 2:54 PM.

Details

Summary

visitAND, when folding and (load) forgets to check which output of
an indexed load is involved, happily folding the updated address
output on the following testcase:

target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"

%typ = type { i32, i32 }

define signext i32 @_Z8access_pP1Tc(%typ* %p, i8 zeroext %type) {

%b = getelementptr inbounds %typ, %typ* %p, i64 0, i32 1
%1 = load i32, i32* %b, align 4
%2 = ptrtoint i32* %b to i64
%3 = and i64 %2, -35184372088833
%4 = inttoptr i64 %3 to i32*
%_msld = load i32, i32* %4, align 4
%zzz = add i32 %1,  %_msld
ret i32 %zzz

}

Fix this by checking ResNo.

I've found a few more places that currently neglect to check for
indexed load, and tightened them up as well, but I don't have test
cases for them. In fact, they might not be triggerable at all,
at least with current targets. Still, better safe than sorry.

Diff Detail

Repository
rL LLVM

Event Timeline

koriakin retitled this revision from to [PR27390] [CodeGen] Reject indexed loads in CombinerDAG..
koriakin updated this object.
koriakin added reviewers: hfinkel, resistor.
koriakin set the repository for this revision to rL LLVM.
koriakin added a subscriber: llvm-commits.
hfinkel added inline comments.Apr 24 2016, 9:50 PM
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
3102 ↗(On Diff #54013)

It is not clear this is necessary; the code below explicitly handles indexed loads:

if (Load->getExtensionType() == ISD::EXTLOAD) {
  NewLoad = DAG.getLoad(Load->getAddressingMode(), ISD::ZEXTLOAD,
                        Load->getValueType(0), SDLoc(Load),
                        Load->getChain(), Load->getBasePtr(),
                        Load->getOffset(), Load->getMemoryVT(),
                        Load->getMemOperand());
  // Replace uses of the EXTLOAD with the new ZEXTLOAD.
  if (Load->getNumValues() == 3) {
    // PRE/POST_INC loads have 3 values.
    SDValue To[] = { NewLoad.getValue(0), NewLoad.getValue(1),
                     NewLoad.getValue(2) };
    CombineTo(Load, To, 3, true);
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6965 ↗(On Diff #54013)

Why?

koriakin planned changes to this revision.Apr 25 2016, 8:05 AM
koriakin added inline comments.
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
3102 ↗(On Diff #54013)

Ah, indeed it does. So it's OK to allow indexed loads here, but we'll need to check if N0.getResNo() is 0. I'll update the patch.

lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6965 ↗(On Diff #54013)

The only caller (DAGCombiner::CombineConsecutiveLoads) doesn't support indexed loads, and I don't see any other place where they're checked for, but I don't actually have any example code that could trigger a problem here.

koriakin updated this object.

This version checks ResNo in visitAnd instead of disallowing indexed loads entirely.

koriakin marked 2 inline comments as done.Apr 25 2016, 8:25 AM
hfinkel accepted this revision.Apr 25 2016, 8:32 AM
hfinkel edited edge metadata.
hfinkel added inline comments.
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6964 ↗(On Diff #54858)

Okay. Please check in DAGCombiner::CombineConsecutiveLoads instead. Otherwise, LGTM.

This revision is now accepted and ready to land.Apr 25 2016, 8:32 AM
koriakin added inline comments.Apr 25 2016, 8:38 AM
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6964 ↗(On Diff #54858)

Hmm, I'm not sure the logic in areNonVolatileConsecutiveLoads works right in the presence of indexed load anyhow (in particular, pre-indexing needs to be taken into account). I'll take a look.

koriakin added inline comments.Apr 25 2016, 8:40 AM
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6964 ↗(On Diff #54858)

Right, areNonVolatileConsecutiveLoads is incorrect for pre-indexed loads - it only takes getOperand(1) into account. So even if some caller can handle the indexing, it'll provide wrong answers.

hfinkel added inline comments.Apr 25 2016, 8:46 AM
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
6964 ↗(On Diff #54858)

Fair enough. This is fine as-is then. Thanks!

This revision was automatically updated to reflect the committed changes.