Skip to content

Instantly share code, notes, and snippets.

@2bits
Created February 26, 2012 21:09
Show Gist options
  • Save 2bits/1919007 to your computer and use it in GitHub Desktop.
Save 2bits/1919007 to your computer and use it in GitHub Desktop.
clang-3.1 (318) error in backend: Couldn't allocate input reg for constraint '{_l_src_pitch}'! <-- llvm is the backend
[ 52%] Building CXX object ADM_videoFilters/FluxSmooth/CMakeFiles/ADM_vf_FluxSmooth.dir/ADM_vidFlux.cpp.o
cd /tmp/homebrew-avidemux-HEAD-pHmH/plgbuild/ADM_videoFilters/FluxSmooth && /usr/bin/clang++ -DADM_vf_FluxSmooth_EXPORTS -Os -w -pipe -march=native -Xclang -target-feature -Xclang -aes -Qunused-arguments -fPIC -I/private/tmp/homebrew-avidemux-HEAD-pHmH -I/private/tmp/homebrew-avidemux-HEAD-pHmH/avidemux/ADM_libraries/ffmpeg -I/private/tmp/homebrew-avidemux-HEAD-pHmH/macbuild/config -I/tmp/homebrew-avidemux-HEAD-pHmH/plugins/ADM_videoFilters/FluxSmooth/. -I/private/tmp/homebrew-avidemux-HEAD-pHmH/avidemux/ADM_core/include -I/private/tmp/homebrew-avidemux-HEAD-pHmH/avidemux/ADM_coreUI/include -I/private/tmp/homebrew-avidemux-HEAD-pHmH/avidemux/ADM_coreImage/include -I/private/tmp/homebrew-avidemux-HEAD-pHmH/avidemux/ADM_plugin -o CMakeFiles/ADM_vf_FluxSmooth.dir/ADM_vidFlux.cpp.o -c /tmp/homebrew-avidemux-HEAD-pHmH/plugins/ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp
fatal error: error in backend: Couldn't allocate input reg for constraint '{_l_src_pitch}'!
make[2]: *** [ADM_videoFilters/FluxSmooth/CMakeFiles/ADM_vf_FluxSmooth.dir/ADM_vidFlux.cpp.o] Error 1
make[1]: *** [ADM_videoFilters/FluxSmooth/CMakeFiles/ADM_vf_FluxSmooth.dir/all] Error 2
make: *** [all] Error 2
Occurs in Avidemux-2.5 svn on 64bit OSX Lion 10.7.3 using Command Line Tools For XCode-4.3, clang++, cmake-2.8.7 and native ld.
I can grep for l_src_pitch in the plugins, and here are the occurrences:
$ findamo l_src_pitch
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:69:static long int FUNNY_MANGLE(_l_src_pitch) ASM_CONST =0;
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:445: _l_src_pitch =src_pitch;
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:505:" sub "Mangle(_l_src_pitch)", "REG_ax" \n\t"
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:536:" add "Mangle(_l_src_pitch)", "REG_ax" \n\t"
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:636:" add "Mangle(_l_src_pitch)", "REG_si" \n\t"
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:638:" add "Mangle(_l_src_pitch)", "REG_ax" \n\t"
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:641:" add "Mangle(_l_src_pitch)", "REG_bx" \n\t"
./ADM_videoFilters/FluxSmooth/ADM_vidFlux.cpp:652: : : "r"(_l_src_pitch) );
llvm source code has the words "allocate input reg for constraint" in only one place,
llvm-3.0/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp: 6191
which comes in a big case statement, case InlineAsm::isInput: {
Here is the entire case statement. The allocate input reg part is down at line 147 of this gist:
========================================================================================================
case InlineAsm::isInput: {
SDValue InOperandVal = OpInfo.CallOperand;
if (OpInfo.isMatchingInputConstraint()) { // Matching constraint?
// If this is required to match an output register we have already set,
// just use its register.
unsigned OperandNo = OpInfo.getMatchedOperand();
// Scan until we find the definition we already emitted of this operand.
// When we find it, create a RegsForValue operand.
unsigned CurOp = InlineAsm::Op_FirstOperand;
for (; OperandNo; --OperandNo) {
// Advance to the next operand.
unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
assert((InlineAsm::isRegDefKind(OpFlag) ||
InlineAsm::isRegDefEarlyClobberKind(OpFlag) ||
InlineAsm::isMemKind(OpFlag)) && "Skipped past definitions?");
CurOp += InlineAsm::getNumOperandRegisters(OpFlag)+1;
}
unsigned OpFlag =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue();
if (InlineAsm::isRegDefKind(OpFlag) ||
InlineAsm::isRegDefEarlyClobberKind(OpFlag)) {
// Add (OpFlag&0xffff)>>3 registers to MatchedRegs.
if (OpInfo.isIndirect) {
// This happens on gcc/testsuite/gcc.dg/pr8788-1.c
LLVMContext &Ctx = *DAG.getContext();
Ctx.emitError(CS.getInstruction(), "inline asm not supported yet:"
" don't know how to handle tied "
"indirect register inputs");
}
RegsForValue MatchedRegs;
MatchedRegs.ValueVTs.push_back(InOperandVal.getValueType());
EVT RegVT = AsmNodeOperands[CurOp+1].getValueType();
MatchedRegs.RegVTs.push_back(RegVT);
MachineRegisterInfo &RegInfo = DAG.getMachineFunction().getRegInfo();
for (unsigned i = 0, e = InlineAsm::getNumOperandRegisters(OpFlag);
i != e; ++i)
MatchedRegs.Regs.push_back
(RegInfo.createVirtualRegister(TLI.getRegClassFor(RegVT)));
// Use the produced MatchedRegs object to
MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
MatchedRegs.AddInlineAsmOperands(InlineAsm::Kind_RegUse,
true, OpInfo.getMatchedOperand(),
DAG, AsmNodeOperands);
break;
}
assert(InlineAsm::isMemKind(OpFlag) && "Unknown matching constraint!");
assert(InlineAsm::getNumOperandRegisters(OpFlag) == 1 &&
"Unexpected number of operands");
// Add information to the INLINEASM node to know about this input.
// See InlineAsm.h isUseOperandTiedToDef.
OpFlag = InlineAsm::getFlagWordForMatchingOp(OpFlag,
OpInfo.getMatchedOperand());
AsmNodeOperands.push_back(DAG.getTargetConstant(OpFlag,
TLI.getPointerTy()));
AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]);
break;
}
// Treat indirect 'X' constraint as memory.
if (OpInfo.ConstraintType == TargetLowering::C_Other &&
OpInfo.isIndirect)
OpInfo.ConstraintType = TargetLowering::C_Memory;
if (OpInfo.ConstraintType == TargetLowering::C_Other) {
std::vector<SDValue> Ops;
TLI.LowerAsmOperandForConstraint(InOperandVal, OpInfo.ConstraintCode,
Ops, DAG);
if (Ops.empty())
report_fatal_error("Invalid operand for inline asm constraint '" +
Twine(OpInfo.ConstraintCode) + "'!");
// Add information to the INLINEASM node to know about this input.
unsigned ResOpType =
InlineAsm::getFlagWord(InlineAsm::Kind_Imm, Ops.size());
AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
TLI.getPointerTy()));
AsmNodeOperands.insert(AsmNodeOperands.end(), Ops.begin(), Ops.end());
break;
}
if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
assert(InOperandVal.getValueType() == TLI.getPointerTy() &&
"Memory operands expect pointer values");
// Add information to the INLINEASM node to know about this input.
unsigned ResOpType = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
TLI.getPointerTy()));
AsmNodeOperands.push_back(InOperandVal);
break;
}
assert((OpInfo.ConstraintType == TargetLowering::C_RegisterClass ||
OpInfo.ConstraintType == TargetLowering::C_Register) &&
"Unknown constraint type!");
assert(!OpInfo.isIndirect &&
"Don't know how to handle indirect register inputs yet!");
// Copy the input into the appropriate registers.
if (OpInfo.AssignedRegs.Regs.empty())
report_fatal_error("Couldn't allocate input reg for constraint '" +
Twine(OpInfo.ConstraintCode) + "'!");
OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(),
Chain, &Flag);
OpInfo.AssignedRegs.AddInlineAsmOperands(InlineAsm::Kind_RegUse, false, 0,
DAG, AsmNodeOperands);
break;
}
========================================================================================================
Threads on llvm.org talk about problems initializing when there's a constant float set or i dunno.
I'm sure I didn't understand it, which is why I'm pasting this and not just patching it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment