Index: lib/Target/ARM/ARMISelDAGToDAG.cpp =================================================================== --- lib/Target/ARM/ARMISelDAGToDAG.cpp +++ lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -4244,6 +4244,17 @@ if (Changed && InlineAsm::isUseOperandTiedToDef(Flag, DefIdx)) IsTiedToChangedOp = OpChanged[DefIdx]; + // Memory operands to inline asm in the SelectionDAG are modeled with two + // operands: a constant of value InlineAsm::Kind_Mem followed by the input + // operand. If we get here and we have a Kind_Mem, skip the next operand (so + // it doesn't get misinterpreted), and continue. We do this here because + // it's important to update the OpChanged array correctly before moving on. + if (Kind == InlineAsm::Kind_Mem) { + SDValue op = N->getOperand(++i); + AsmNodeOperands.push_back(op); + continue; + } + if (Kind != InlineAsm::Kind_RegUse && Kind != InlineAsm::Kind_RegDef && Kind != InlineAsm::Kind_RegDefEarlyClobber) continue; Index: test/CodeGen/ARM/inlineasm3.ll =================================================================== --- test/CodeGen/ARM/inlineasm3.ll +++ test/CodeGen/ARM/inlineasm3.ll @@ -121,3 +121,11 @@ %0 = tail call <4 x i32> asm "vld1.s32 {${0:e}[], ${0:f}[]}, [$1]", "=w,r"(i32* %p) nounwind ret <4 x i32> %0 } + +; Bugzilla PR26038 + +define i32 @fn1() local_unnamed_addr nounwind { +entry: + %0 = tail call i32 asm "ldrh $0, $1", "=r,*Q"(i8* inttoptr (i32 5 to i8*)) nounwind + ret i32 %0 +}