From 3836dbd3bde1100c1df847a582784cf83d18daf6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 20 Sep 2006 04:25:47 +0000 Subject: [PATCH] Two improvements: 1. Codegen this comparison: if (X == 0x8000) as: cmplwi cr0, r3, 32768 bne cr0, LBB1_2 ;cond_next instead of: lis r2, 0 ori r2, r2, 32768 cmpw cr0, r3, r2 bne cr0, LBB1_2 ;cond_next 2. Codegen this comparison: if (X == 0x12345678) as: xoris r2, r3, 4660 cmplwi cr0, r2, 22136 bne cr0, LBB1_2 ;cond_next instead of: lis r2, 4660 ori r2, r2, 22136 cmpw cr0, r3, r2 bne cr0, LBB1_2 ;cond_next git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30509 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 28 +++++++++++++++++++++++++- lib/Target/PowerPC/README.txt | 21 ------------------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 4662e531a9e..70b2aa0577d 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -699,7 +699,33 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS, if (LHS.getValueType() == MVT::i32) { unsigned Imm; - if (ISD::isUnsignedIntSetCC(CC)) { + if (CC == ISD::SETEQ || CC == ISD::SETNE) { + if (isInt32Immediate(RHS, Imm)) { + // SETEQ/SETNE comparison with 16-bit immediate, fold it. + if (isUInt16(Imm)) + return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS, + getI32Imm(Imm & 0xFFFF)), 0); + // If this is a 16-bit signed immediate, fold it. + if (isInt16(Imm)) + return SDOperand(CurDAG->getTargetNode(PPC::CMPWI, MVT::i32, LHS, + getI32Imm(Imm & 0xFFFF)), 0); + + // For non-equality comparisons, the default code would materialize the + // constant, then compare against it, like this: + // lis r2, 4660 + // ori r2, r2, 22136 + // cmpw cr0, r3, r2 + // Since we are just comparing for equality, we can emit this instead: + // xoris r0,r3,0x1234 + // cmplwi cr0,r0,0x5678 + // beq cr0,L6 + SDOperand Xor(CurDAG->getTargetNode(PPC::XORIS, MVT::i32, LHS, + getI32Imm(Imm >> 16)), 0); + return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, Xor, + getI32Imm(Imm & 0xFFFF)), 0); + } + Opc = PPC::CMPLW; + } else if (ISD::isUnsignedIntSetCC(CC)) { if (isInt32Immediate(RHS, Imm) && isUInt16(Imm)) return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt index cfc7eb38b28..4f7f2cff10b 100644 --- a/lib/Target/PowerPC/README.txt +++ b/lib/Target/PowerPC/README.txt @@ -50,27 +50,6 @@ we don't have to always run the branch selector for small functions. ===-------------------------------------------------------------------------=== -* Codegen this: - - void test2(int X) { - if (X == 0x12345678) bar(); - } - - as: - - xoris r0,r3,0x1234 - cmplwi cr0,r0,0x5678 - beq cr0,L6 - - not: - - lis r2, 4660 - ori r2, r2, 22136 - cmpw cr0, r3, r2 - bne .LBB_test2_2 - -===-------------------------------------------------------------------------=== - Lump the constant pool for each function into ONE pic object, and reference pieces of it as offsets from the start. For functions like this (contrived to have lots of constants obviously):