Skip to content

Commit 73ed44d

Browse files
committedJul 18, 2016
[ARM] Skip inline asm memory operands in DAGToDAGISel
The current logic for handling inline asm operands in DAGToDAGISel interprets the operands by looking for constants, which should represent the flags describing the kind of operand we're dealing with (immediate, memory, register def etc). The operands representing actual data are skipped only if they are non-const, with the exception of immediate operands which are skipped explicitly when a flag describing an immediate is found. The oversight is that memory operands may be const too (e.g. for device drivers reading a fixed address), so we should explicitly skip the operand following a flag describing a memory operand. If we don't, we risk interpreting that constant as a flag, which is definitely not intended. Fixes PR26038 Differential Revision: https://reviews.llvm.org/D22103 llvm-svn: 275776
1 parent a3c55f5 commit 73ed44d

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed
 

‎llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -4264,6 +4264,17 @@ bool ARMDAGToDAGISel::tryInlineAsm(SDNode *N){
42644264
if (Changed && InlineAsm::isUseOperandTiedToDef(Flag, DefIdx))
42654265
IsTiedToChangedOp = OpChanged[DefIdx];
42664266

4267+
// Memory operands to inline asm in the SelectionDAG are modeled with two
4268+
// operands: a constant of value InlineAsm::Kind_Mem followed by the input
4269+
// operand. If we get here and we have a Kind_Mem, skip the next operand (so
4270+
// it doesn't get misinterpreted), and continue. We do this here because
4271+
// it's important to update the OpChanged array correctly before moving on.
4272+
if (Kind == InlineAsm::Kind_Mem) {
4273+
SDValue op = N->getOperand(++i);
4274+
AsmNodeOperands.push_back(op);
4275+
continue;
4276+
}
4277+
42674278
if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef
42684279
&& Kind != InlineAsm::Kind_RegDefEarlyClobber)
42694280
continue;

‎llvm/test/CodeGen/ARM/inlineasm3.ll

+11
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,14 @@ entry:
121121
%0 = tail call <4 x i32> asm "vld1.s32 {${0:e}[], ${0:f}[]}, [$1]", "=w,r"(i32* %p) nounwind
122122
ret <4 x i32> %0
123123
}
124+
125+
; Bugzilla PR26038
126+
127+
define i32 @fn1() local_unnamed_addr nounwind {
128+
; CHECK-LABEL: fn1
129+
entry:
130+
; CHECK: mov [[addr:r[0-9]+]], #5
131+
; CHECK: ldrh {{.*}}[[addr]]
132+
%0 = tail call i32 asm "ldrh $0, $1", "=r,*Q"(i8* inttoptr (i32 5 to i8*)) nounwind
133+
ret i32 %0
134+
}

0 commit comments

Comments
 (0)
Please sign in to comment.