I have a question about the pattern matching stuff that's used in the
Instruction Combiner. If I have code like this:
if (match(B, m_Select(m_Value(), m_ConstantInt(0),
m_ConstantInt(-1)))) {
if (match(C, m_Not(m_Value(B))))
return SelectInst::Create(cast<User>(B)->getOperand(0), D, A);
and we match, the program fails during the "SelectInst::Create" phase.
The problem is because B is now a Constant with "-2" as its value, so
it has 0 operands. It appears that the m_Not() match is changing the
value of B during this call.
Is this intentional? This happens in the "bind_ty" template in
PatternMatch.h:
template<typename Class>
struct bind_ty {
Class *&VR;
bind_ty(Class *&V) : VR(V) {}
template<typename ITy>
bool match(ITy *V) {
if (Class *CV = dyn_cast<Class>(V)) {
VR = CV;
return true;
}
return false;
}
};
Why are we taking a reference to a pointer here? The assignment in the
"match" method over writes the value of "B", which seems
weird and
wrong to me.
-bw
Bill Wendling wrote:> I have a question about the pattern matching stuff that's used in the > Instruction Combiner. If I have code like this: > > if (match(B, m_Select(m_Value(), m_ConstantInt(0), > m_ConstantInt(-1)))) { > if (match(C, m_Not(m_Value(B)))) > return SelectInst::Create(cast<User>(B)->getOperand(0), D, A); > > and we match, the program fails during the "SelectInst::Create" phase. > The problem is because B is now a Constant with "-2" as its value, so > it has 0 operands. It appears that the m_Not() match is changing the > value of B during this call. > > Is this intentional? This happens in the "bind_ty" template in > PatternMatch.h: > > template<typename Class> > struct bind_ty { > Class *&VR; > bind_ty(Class *&V) : VR(V) {} > > template<typename ITy> > bool match(ITy *V) { > if (Class *CV = dyn_cast<Class>(V)) { > VR = CV; > return true; > } > return false; > } > }; > > Why are we taking a reference to a pointer here? The assignment in the > "match" method over writes the value of "B", which seems weird and > wrong to me.This is deliberate. m_Foo(V) means "match any Foo and put its result into V." The way it's generally used is to declare empty variables, match against them, and test the equality: Value *A, *B, *C, *D; if (match(Expr, m_Or(m_And(A, B), m_And(C, D))) { if (B == D) { ... do optimization ... Nick> -bw > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On Nov 9, 2008, at 7:51 AM, Nick Lewycky wrote:> Bill Wendling wrote: >> Why are we taking a reference to a pointer here? The assignment in >> the >> "match" method over writes the value of "B", which seems weird and >> wrong to me. > > This is deliberate. m_Foo(V) means "match any Foo and put its result > into V." The way it's generally used is to declare empty variables, > match against them, and test the equality: > > Value *A, *B, *C, *D; > if (match(Expr, m_Or(m_And(A, B), m_And(C, D))) { > if (B == D) { > ... do optimization ... >Ah! Okay. Thanks for the explanation. -bw
Maybe Matching Threads
- [LLVMdev] m_Not Pattern Question
- [LLVMdev] Cast instructions
- [LLVMdev] [llvm-commits] [llvm] r92458 - in /llvm/trunk: lib/Target/README.txt lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/or.ll
- failing to optimize boolean ops on cmps
- Hitting assertion failure related to vectorization + instcombine