diff options
| author | Bill Wendling <isanbard@gmail.com> | 2008-11-09 23:17:42 +0000 | 
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2008-11-09 23:17:42 +0000 | 
| commit | 1579287550505d49e2cb1adcd696bfbe6f969db0 (patch) | |
| tree | 9692bbc078288889751fea59cecfce90830e8906 /llvm/lib | |
| parent | 8ad00b26eee7044ca0e6912e0b3be770526ec8e8 (diff) | |
| download | bcm5719-llvm-1579287550505d49e2cb1adcd696bfbe6f969db0.tar.gz bcm5719-llvm-1579287550505d49e2cb1adcd696bfbe6f969db0.zip  | |
The method of doing the matching with a 'select' instruction was wrong. The
original code was matching like this:
	if (match(A, m_Not(m_Value(B))))
B was already matched as a 'select' instruction. However, this isn't matching
what we think it's matching. It would match B as a 'Value', so basically
anything would match to it. In this case, a Constant matched. B was replaced
with a constant representation. And then the wrong value would be used in the
SelectInst::Create statement, causing a crash.
After thinking on this for a moment, and after Nick L. told me how the pattern
matching stuff was supposed to work, the solution was to match NOT an m_Value,
but an m_Select.
llvm-svn: 58946
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 71 | 
1 files changed, 39 insertions, 32 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 60b907e0da9..fa0704cc404 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -4352,55 +4352,62 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {        }      } +#define SELECT_MATCH(Val) \ +    m_Select(m_Value(Val), m_ConstantInt(0), m_ConstantInt(-1)) +#define GET_SELECT_COND(Val) \ +    cast<User>(Val)->getOperand(0) +      // (A & (C0?-1:0)) | (B & ~(C0?-1:0)) ->  C0 ? A : B, and commuted variants      if (match(A, m_Select(m_Value(), m_ConstantInt(-1), m_ConstantInt(0)))) { -      if (match(D, m_Not(m_Value(A)))) -        return SelectInst::Create(cast<User>(A)->getOperand(0), C, B); -      if (match(B, m_Not(m_Value(A)))) -        return SelectInst::Create(cast<User>(A)->getOperand(0), C, D); +      if (match(D, m_Not(SELECT_MATCH(A)))) +        return SelectInst::Create(GET_SELECT_COND(D), C, B); +      if (match(B, m_Not(SELECT_MATCH(A)))) +        return SelectInst::Create(GET_SELECT_COND(B), C, D);      }      if (match(B, m_Select(m_Value(), m_ConstantInt(-1), m_ConstantInt(0)))) { -      if (match(C, m_Not(m_Value(B)))) -        return SelectInst::Create(cast<User>(B)->getOperand(0), A, D); -      if (match(A, m_Not(m_Value(B)))) -        return SelectInst::Create(cast<User>(B)->getOperand(0), C, D); +      if (match(C, m_Not(SELECT_MATCH(B)))) +        return SelectInst::Create(GET_SELECT_COND(C), A, D); +      if (match(A, m_Not(SELECT_MATCH(B)))) +        return SelectInst::Create(GET_SELECT_COND(A), C, D);      }      if (match(C, m_Select(m_Value(), m_ConstantInt(-1), m_ConstantInt(0)))) { -      if (match(D, m_Not(m_Value(C)))) -        return SelectInst::Create(cast<User>(C)->getOperand(0), A, B); -      if (match(B, m_Not(m_Value(C)))) -        return SelectInst::Create(cast<User>(C)->getOperand(0), A, D); +      if (match(D, m_Not(SELECT_MATCH(C)))) +        return SelectInst::Create(GET_SELECT_COND(D), A, B); +      if (match(B, m_Not(SELECT_MATCH(C)))) +        return SelectInst::Create(GET_SELECT_COND(B), A, D);      }      if (match(D, m_Select(m_Value(), m_ConstantInt(-1), m_ConstantInt(0)))) { -      if (match(C, m_Not(m_Value(D)))) -        return SelectInst::Create(cast<User>(D)->getOperand(0), A, B); -      if (match(A, m_Not(m_Value(D)))) -        return SelectInst::Create(cast<User>(D)->getOperand(0), C, B); +      if (match(C, m_Not(SELECT_MATCH(D)))) +        return SelectInst::Create(GET_SELECT_COND(C), A, B); +      if (match(A, m_Not(SELECT_MATCH(D)))) +        return SelectInst::Create(GET_SELECT_COND(A), C, B);      }      if (match(A, m_Select(m_Value(), m_ConstantInt(0), m_ConstantInt(-1)))) { -      if (match(D, m_Not(m_Value(A)))) -        return SelectInst::Create(cast<User>(A)->getOperand(0), B, C); -      if (match(B, m_Not(m_Value(A)))) -        return SelectInst::Create(cast<User>(A)->getOperand(0), D, C); +      if (match(D, m_Not(SELECT_MATCH(A)))) +        return SelectInst::Create(GET_SELECT_COND(D), B, C); +      if (match(B, m_Not(SELECT_MATCH(A)))) +        return SelectInst::Create(GET_SELECT_COND(B), D, C);      }      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); -      if (match(A, m_Not(m_Value(B)))) -        return SelectInst::Create(cast<User>(B)->getOperand(0), D, C); +      if (match(C, m_Not(SELECT_MATCH(B)))) +        return SelectInst::Create(GET_SELECT_COND(C), D, A); +      if (match(A, m_Not(SELECT_MATCH(B)))) +        return SelectInst::Create(GET_SELECT_COND(A), D, C);      }      if (match(C, m_Select(m_Value(), m_ConstantInt(0), m_ConstantInt(-1)))) { -      if (match(D, m_Not(m_Value(C)))) -        return SelectInst::Create(cast<User>(C)->getOperand(0), B, A); -      if (match(B, m_Not(m_Value(C)))) -        return SelectInst::Create(cast<User>(C)->getOperand(0), D, A); +      if (match(D, m_Not(SELECT_MATCH(C)))) +        return SelectInst::Create(GET_SELECT_COND(D), B, A); +      if (match(B, m_Not(SELECT_MATCH(C)))) +        return SelectInst::Create(GET_SELECT_COND(B), D, A);      }      if (match(D, m_Select(m_Value(), m_ConstantInt(0), m_ConstantInt(-1)))) { -      if (match(C, m_Not(m_Value(D)))) -        return SelectInst::Create(cast<User>(D)->getOperand(0), B, A); -      if (match(A, m_Not(m_Value(D)))) -        return SelectInst::Create(cast<User>(D)->getOperand(0), B, C); +      if (match(C, m_Not(SELECT_MATCH(D)))) +        return SelectInst::Create(GET_SELECT_COND(C), B, A); +      if (match(A, m_Not(SELECT_MATCH(D)))) +        return SelectInst::Create(GET_SELECT_COND(A), B, C);      } +#undef SELECT_MATCH +#undef GET_SELECT_COND    }    // (X >> Z) | (Y >> Z)  -> (X|Y) >> Z  for all shifts.  | 

