- if (!CO && !BO)
- return NULL;
-
- Value* Op0 = NULL;
- Value* Op1 = NULL;
- unsigned Opcode = 0;
- if (CO && ((CO->getOpcode() == Instruction::Mul) ||
- (CO->getOpcode() == Instruction::Shl))) {
- Op0 = CO->getOperand(0);
- Op1 = CO->getOperand(1);
- Opcode = CO->getOpcode();
- }
- if (BO && ((BO->getOpcode() == Instruction::Mul) ||
- (BO->getOpcode() == Instruction::Shl))) {
- Op0 = BO->getOperand(0);
- Op1 = BO->getOperand(1);
- Opcode = BO->getOpcode();
- }
-
- // Determine array size if malloc's argument is the product of a mul or shl.
- if (Op0) {
- if (Opcode == Instruction::Mul) {
- if ((Op1 == ElementSize) ||
- (FoldedElementSize && (Op1 == FoldedElementSize)))
- // ArraySize * ElementSize
- return Op0;
- if ((Op0 == ElementSize) ||
- (FoldedElementSize && (Op0 == FoldedElementSize)))
- // ElementSize * ArraySize
- return Op1;
- }
- if (Opcode == Instruction::Shl) {
- ConstantInt* Op1CI = dyn_cast<ConstantInt>(Op1);
- if (!Op1CI) return NULL;
-
- APInt Op1Int = Op1CI->getValue();
- unsigned Op1Width = Op1Int.getBitWidth();
- // check for overflow
- if (Op1Int.getActiveBits() > 64 || Op1Int.getZExtValue() > Op1Width)
- return NULL;
- Value* Op1Pow = ConstantInt::get(Context,
- APInt(Op1Width, 0).set(Op1Int.getZExtValue()));
-
- if (Op0 == ElementSize || (FoldedElementSize && Op0 == FoldedElementSize))
- // ArraySize << log2(ElementSize)
- return Op1Pow;
- if (Op1Pow == ElementSize ||
- (FoldedElementSize && Op1Pow == FoldedElementSize))
- // ElementSize << log2(ArraySize)
- return Op0;
- }
- }
-
- // We could not determine the malloc array size from MallocArg.