diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 83357e066009..b9b518afc006 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -2405,11 +2405,24 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, // 'X' matches anything. if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) { + // Look through bitcasts over functions. In the context of an asm + // argument we don't care about bitcasting function types; the parameters + // to the function, if any, will have been handled elsewhere. + Value *v = OpInfo.CallOperandVal; + ConstantExpr *CE = NULL; + while ((CE = dyn_cast(v)) && + CE->getOpcode()==Instruction::BitCast) + v = CE->getOperand(0); + if (!isa(v)) + v = OpInfo.CallOperandVal; // Labels and constants are handled elsewhere ('X' is the only thing - // that matches labels). - if (isa(OpInfo.CallOperandVal) || - isa(OpInfo.CallOperandVal)) + // that matches labels). For Functions, the type here is the type of + // the result, which is not what we want to look at; leave them alone + // (minus any bitcasts). + if (isa(v) || isa(v) || isa(v)) { + OpInfo.CallOperandVal = v; return; + } // Otherwise, try to resolve it to something we know about by looking at // the actual operand type.