Currently on PowerPC, llvm does not expand calls to memcmp as it does for memcpy, memmove. When memcmp size and alignment info of the two sources being compared is known at compile time, we can do an inline expansion rather than calling the library routine.
To start, only the expansion for multiples of 8 bytes is added. This expansion loads 8 bytes from the two sources to compare, subtracts to see if there was a difference, and then does an early exit if a difference was found. Otherwise, continues to the next 8 bytes.
The implementation uses the current infrastructure by overriding the existing virtual function:
virtual std::pair<SDValue, SDValue> EmitTargetCodeForMemcmp(SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2, SDValue Op3, MachinePointerInfo Op1PtrInfo, MachinePointerInfo Op2PtrInfo) const { return std::make_pair(SDValue(), SDValue()); }
found in include/llvm/CodeGen/SelectionDAGTargetInfo.h
This function is called from bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) in lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp. It is implemented by some other targets but was not yet added for PowerPC. So, the current behavior is that it returns a null value and the memcmp is left as a library call.
The implementation for PowerPC for EmitTargetCodeForMemcmp is now added. However, this function does the expansion on a SelectionDAG. Since the expansion requires control flow for early exits, rather than implementing the expansion at the SelectionDAG level, a new pseudo instruction for memcmp is added and a SelectionDAG node with this new pseudo instruction is created. The memcmp pseudo instruction is then expanded during lowering in lib/Target/PowerPC/PPCISelLowering.cpp in the function:
MachineBasicBlock * PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const