Hi,
I'm doing a backend port and I'm having trouble with adds that have
negative immediates.
My architecture only has instructions for subtracting and adding 8bit
immediate values (they will be zero-extended, thus unsigned).
Bigger immediates have to be moved in a register first.
The problem is:
Expressions like "b - 1" result in "add nsw i32 %b, -1" in
LLVM IR.
They cannot be matched to the 8bit unsigned immediate add during
Instruction Selection and will eventually be moved in a register.
It would be better to transform these adds with small negative
immediates into subs during Target Lowering.
So I tried to custom lower ISD::ADD in IselLowering:
MxmTargetLowering::MxmTargetLowering(TargetMachine &TM)
: TargetLowering(TM, new TargetLoweringObjectFileELF()) {
[...]
setOperationAction(ISD::ADD, MVT::i32, Custom);
[...]
}
//check for immediate adds with constant values -256 < x < 0 and
transform them
//to sub
SDValue MxmTargetLowering::LowerADD(SDValue Op, SelectionDAG &DAG) const {
SDValue Op0 = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1);
if(ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op1)) {
int val = CN->getSExtValue();
if(val < 0 && val > -256) {
return DAG.getNode(ISD::SUB, dl, MVT::i32,
Op0,DAG.getConstant(-val, MVT::i32));
}
}
return Op;
}
SDValue MxmTargetLowering::
LowerOperation(SDValue Op, SelectionDAG &DAG) const {
switch(Op.getOpcode()) {
case ISD::GlobalAddress:
return LowerGlobalAddress(Op, DAG);
case ISD::ConstantPool:
return LowerConstantPool(Op,DAG);
case ISD::ADD:
return LowerADD(Op,DAG);
default:
llvm_unreachable("illegal custom lowering operation");
}
}
Unfortunately, this has absolutely no effect. The resultig ISel-DAG has
still the adds with negative immediates.
Maybe I'm doing it completely wrong. Could anyone give me some advice
with that?
Jan Tlatlik