Hello everyone,
I am working on some changes to the Hexagon VLIW PreRA scheduler, and as a
part of it need to test aliasing properties of two instruction.
What it boils down to is the following code:
char a[20];
char s;
char *p, *q; // p == &a[0]; q == &s;
void test()
{
register char reg;
s = 0;
reg = p[0] + p[1];
s = q[0] + reg;
return;
}
When I ask the question whether "&s" and "&q[0]" may
potentially alias, I
got negative affirmation.
In the full test (not presented) they indeed may and do in fact alias,
resulting in incorrect VLIW schedule.
My question - is it a feature or a bug :)
Here is somewhat more info:
Before lowering begins:
*** IR Dump After Remove sign extends ***
define void @test() nounwind {
entry:
store i8 0, i8* @s, align 1, !tbaa !0
%0 = load i8** @p, align 4, !tbaa !2
%1 = load i8* %0, align 1, !tbaa !0
%conv = zext i8 %1 to i32
%arrayidx1 = getelementptr inbounds i8* %0, i32 1
%2 = load i8* %arrayidx1, align 1, !tbaa !0
%conv2 = zext i8 %2 to i32
%3 = load i8** @q, align 4, !tbaa !2 <<< Can this load be bypassed by
the
store below?
%4 = load i8* %3, align 1, !tbaa !0
%conv5 = zext i8 %4 to i32
%add = add i32 %conv2, %conv
%add7 = add i32 %add, %conv5
%conv8 = trunc i32 %add7 to i8
store i8 %conv8, i8* @s, align 1, !tbaa !0 <<< Can this store bypass
the
above load?
ret void
}
At the point of enquiry I have the following (lowered) instructions:
x3df7900: i32,ch = LDw_GP_V4 0x3df4c70, 0x3df5470<Mem:LD4[@q](tbaa=!"any
pointer")> [ORD=8] [ID=6] // This is Load from q[0]
0x3df5470: ch = STb_GP_V4 0x3df5170, 0x3df4e70, 0x3d9c130<Mem:ST1[@s]>
[ID=4] // This is a store to s
Underlying Values:
@q = common global i8* null, align 4
@s = common global i8 0, align 1
The way inquiry is made is similar to DAGCombiner::isAlias()
SDNode *SDN1;
SDNode *SDN2;
MachineMemOperand *MMOa;
MachineMemOperand *MMOb;
...
const MachineSDNode *MNb = dyn_cast<MachineSDNode>(SDN2);
const MachineSDNode *MNa = dyn_cast<MachineSDNode>(SDN1);
...
MMOa = !MNa->memoperands_empty() ?
(*MNa->memoperands_begin()) : NULL;
MMOb = !MNb->memoperands_empty() ?
(*MNb->memoperands_begin()) : NULL;
if (MMOa && MMOa->getValue() && MMOb &&
MMOb->getValue()) {
...
int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset());
int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset;
int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset;
AliasAnalysis::AliasResult AAResult = AA->alias(
AliasAnalysis::Location(MMOa->getValue(), Overlapa,
MMOa->getTBAAInfo()),
AliasAnalysis::Location(MMOb->getValue(), Overlapb,
MMOb->getTBAAInfo()));
Quick debug of BasicAliasAnalysis::aliasCheck() points to this code:
if (isIdentifiedObject(O1) && isIdentifiedObject(O2))
return NoAlias;
And in llvm::isIdentifiedObject() this is true:
if (isa<GlobalValue>(V) && !isa<GlobalAlias>(V))
Any qlues/suggestions are welcome. Thanks.
Sergei Larin
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum.