From 2231d21dadaa05046e2c647ce153615e99cfad92 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 30 Nov 2004 07:30:20 +0000 Subject: [PATCH] Fix several bugs in 'op x, imm' handling. Foremost is that we now emit addi r3, r3, -1 instead of addi r3, r3, 1 for 'sub int X, 1'. Secondarily, this fixes several cases where we could crash given an unsigned constant. And fixes a couple of minor missed optimization cases, such as xor X, ~0U -> not X llvm-svn: 18379 --- lib/Target/PowerPC/PPC32ISelSimple.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/Target/PowerPC/PPC32ISelSimple.cpp b/lib/Target/PowerPC/PPC32ISelSimple.cpp index 1314087b7f9..bd6c7e46d9f 100644 --- a/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -2323,24 +2323,20 @@ void PPC32ISel::emitBinaryConstOperation(MachineBasicBlock *MBB, { PPC::ADDIS, PPC::ADDIS, PPC::ANDISo, PPC::ORIS, PPC::XORIS, PPC::SUBFIC } }; - // Handle subtract now by inverting the constant value - ConstantInt *CI = Op1; + // Handle subtract now by inverting the constant value: X-4 == X+(-4) if (Opcode == 1) { - ConstantSInt *CSI = dyn_cast(Op1); - CI = ConstantSInt::get(Op1->getType(), -CSI->getValue()); + Op1 = cast(ConstantExpr::getNeg(Op1)); + Opcode = 0; } // xor X, -1 -> not X - if (Opcode == 4) { - ConstantInt *CI = dyn_cast(Op1); - if (CI && CI->isAllOnesValue()) { - BuildMI(*MBB, IP, PPC::NOR, 2, DestReg).addReg(Op0Reg).addReg(Op0Reg); - return; - } + if (Opcode == 4 && Op1->isAllOnesValue()) { + BuildMI(*MBB, IP, PPC::NOR, 2, DestReg).addReg(Op0Reg).addReg(Op0Reg); + return; } - if (Opcode == 2 && !CI->isNullValue()) { - unsigned MB, ME, mask = CI->getRawValue(); + if (Opcode == 2 && !Op1->isNullValue()) { + unsigned MB, ME, mask = Op1->getRawValue(); if (isRunOfOnes(mask, MB, ME)) { BuildMI(*MBB, IP, PPC::RLWINM, 4, DestReg).addReg(Op0Reg).addImm(0) .addImm(MB).addImm(ME); @@ -2358,14 +2354,14 @@ void PPC32ISel::emitBinaryConstOperation(MachineBasicBlock *MBB, // For Add, Sub, and SubF the instruction takes a signed immediate. For And, // Or, and Xor, the instruction takes an unsigned immediate. There is no // shifted immediate form of SubF so disallow its opcode for those constants. - if (canUseAsImmediateForOpcode(CI, Opcode, false)) { + if (canUseAsImmediateForOpcode(Op1, Opcode, false)) { if (Opcode < 2 || Opcode == 5) BuildMI(*MBB, IP, ImmOpTab[0][Opcode], 2, DestReg).addReg(Op0Reg) .addSImm(Op1->getRawValue()); else BuildMI(*MBB, IP, ImmOpTab[0][Opcode], 2, DestReg).addReg(Op0Reg) .addZImm(Op1->getRawValue()); - } else if (canUseAsImmediateForOpcode(CI, Opcode, true) && (Opcode < 5)) { + } else if (canUseAsImmediateForOpcode(Op1, Opcode, true) && (Opcode < 5)) { if (Opcode < 2) BuildMI(*MBB, IP, ImmOpTab[1][Opcode], 2, DestReg).addReg(Op0Reg) .addSImm(Op1->getRawValue() >> 16);