[llvm-bugs] [Bug 46239] New: [DAGCombiner, BigEndian] wrong-code resulting in visitSRL()
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Jun 8 01:22:40 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=46239
Bug ID: 46239
Summary: [DAGCombiner, BigEndian] wrong-code resulting in
visitSRL()
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Common Code Generator Code
Assignee: unassignedbugs at nondot.org
Reporter: paulsson at linux.vnet.ibm.com
CC: llvm-bugs at lists.llvm.org
Created attachment 23589
--> https://bugs.llvm.org/attachment.cgi?id=23589&action=edit
reduced testcase
I came across a csmith wrong-code test case which seems to involve the
DAGCombiner, more precisely visitSRL().
In the reduced test case, two i16 values are loaded and and:ed after the first
load having been shifted right logically 8 bits.
The DAGCombiner inteds to replace the srl + load with a zero-extending load
into @d with an added immediate offset. The offset is however incorrectly
computed to 0, which then gives the result of simply dropping the srl, which is
wrong:
llc -mtriple=s390x-linux-gnu -mcpu=z15 -O3 -o out.s tc_lshr_load.ll
define i32 @fun() {
entry:
%0 = load i16, i16* @d, align 2
%1 = lshr i16 %0, 8
%2 = load i16, i16* @g, align 2
%and7 = and i16 %1, %2
store i16 %and7, i16* @d, align 2
ret i32 0
}
Initial selection DAG: %bb.0 'fun:entry'
SelectionDAG has 17 nodes:
t0: ch = EntryToken
t2: i64 = Constant<0>
t4: i16,ch = load<(dereferenceable load 2 from @d)> t0,
GlobalAddress:i64<i16* @d> 0, undef:i64
t5: i16 = Constant<8>
t9: i16,ch = load<(dereferenceable load 2 from @g)> t0,
GlobalAddress:i64<i16* @g> 0, undef:i64
t11: ch = TokenFactor t4:1, t9:1
t7: i16 = srl t4, Constant:i32<8>
t10: i16 = and t7, t9
t12: ch = store<(store 2 into @d)> t11, t10, GlobalAddress:i64<i16* @d> 0,
undef:i64
t15: ch,glue = CopyToReg t12, Register:i32 $r2l, Constant:i32<0>
t16: ch = SystemZISD::RET_FLAG t15, Register:i32 $r2l, t15:1
...
Combining: t7: i16 = srl t4, Constant:i32<8>
... into: t21: i16,ch = load<(dereferenceable load 1 from @d, align 2), zext
from i8> t0, GlobalAddress:i64<i16* @d> 0, undef:i64
...
Optimized lowered selection DAG: %bb.0 'fun:entry'
SelectionDAG has 13 nodes:
t0: ch = EntryToken
t9: i16,ch = load<(dereferenceable load 2 from @g)> t0,
GlobalAddress:i64<i16* @g> 0, undef:i64
t10: i16 = and t21, t9
t17: ch = store<(store 2 into @d)> t21:1, t10, GlobalAddress:i64<i16* @d>
0, undef:i64
t19: ch = TokenFactor t17, t9:1
t15: ch,glue = CopyToReg t19, Register:i32 $r2l, Constant:i32<0>
t21: i16,ch = load<(dereferenceable load 1 from @d, align 2), zext from i8>
t0, GlobalAddress:i64<i16* @d> 0, undef:i64
t16: ch = SystemZISD::RET_FLAG t15, Register:i32 $r2l, t15:1
The end result is an NC (AND mem/mem) with two 0 offsets, which is clearly
wrong:
larl %r1, d
larl %r2, g
nc 0(2,%r1), 0(%r2)
lhi %r2, 0
br %r14
I beleive the problem to lie in DAGCombiner::ReduceLoadWidth():
auto AdjustBigEndianShift = [&](unsigned ShAmt) {
unsigned LVTStoreBits = LN0->getMemoryVT().getStoreSizeInBits();
unsigned EVTStoreBits = ExtVT.getStoreSizeInBits();
return LVTStoreBits - EVTStoreBits - ShAmt;
};
// For big endian targets, we need to adjust the offset to the pointer to
// load the correct bytes.
if (DAG.getDataLayout().isBigEndian())
ShAmt = AdjustBigEndianShift(ShAmt);
ShAmt is 8 when passed to AdjustBigEndianShift(), but a 0 is returned. It looks
to me that 8 is actually the correct value which in this case should not be
altered.
--
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/20200608/48f2d8e2/attachment.html>
More information about the llvm-bugs
mailing list