[llvm-commits] [llvm] r168262 - in /llvm/trunk: include/llvm/Constants.h lib/VMCore/Constants.cpp unittests/VMCore/ConstantsTest.cpp

Chris Lattner clattner at apple.com
Sun Nov 25 09:10:36 PST 2012


On Nov 17, 2012, at 9:56 AM, James Molloy <James.Molloy at arm.com> wrote:

> Author: jamesm
> Date: Sat Nov 17 11:56:30 2012
> New Revision: 168262
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=168262&view=rev
> Log:
> Add a new function to ConstantExpr - getAsInstruction. This returns its Instruction* corollary, which may be useful if a user
> wishes to transform a ConstantExpr so that one of its operands is no longer constant.

Hi James,

Please don't include the bugzilla link in the code itself.  If you want to keep the two associated, mention it in the commit message.  Thanks!

-Chris

> 
> 
> Modified:
>    llvm/trunk/include/llvm/Constants.h
>    llvm/trunk/lib/VMCore/Constants.cpp
>    llvm/trunk/unittests/VMCore/ConstantsTest.cpp
> 
> Modified: llvm/trunk/include/llvm/Constants.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=168262&r1=168261&r2=168262&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Constants.h (original)
> +++ llvm/trunk/include/llvm/Constants.h Sat Nov 17 11:56:30 2012
> @@ -1076,6 +1076,16 @@
>   /// current one.
>   Constant *getWithOperands(ArrayRef<Constant*> Ops, Type *Ty) const;
> 
> +  /// getAsInstruction - Returns an Instruction which implements the same operation
> +  /// as this ConstantExpr. The instruction is not linked to any basic block.
> +  ///
> +  /// A better approach to this could be to have a constructor for Instruction
> +  /// which would take a ConstantExpr parameter, but that would have spread 
> +  /// implementation details of ConstantExpr outside of Constants.cpp, which 
> +  /// would make it harded to remove ConstantExprs altogether
> +  /// (http://llvm.org/bugs/show_bug.cgi?id=10368).
> +  Instruction *getAsInstruction();
> +
>   virtual void destroyConstant();
>   virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
> 
> 
> Modified: llvm/trunk/lib/VMCore/Constants.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=168262&r1=168261&r2=168262&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Constants.cpp (original)
> +++ llvm/trunk/lib/VMCore/Constants.cpp Sat Nov 17 11:56:30 2012
> @@ -2704,3 +2704,66 @@
>   // Delete the old constant!
>   destroyConstant();
> }
> +
> +Instruction *ConstantExpr::getAsInstruction() {
> +  SmallVector<Value*,4> ValueOperands;
> +  for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
> +    ValueOperands.push_back(cast<Value>(I));
> +
> +  ArrayRef<Value*> Ops(ValueOperands);
> +
> +  switch (getOpcode()) {
> +  case Instruction::Trunc:
> +  case Instruction::ZExt:
> +  case Instruction::SExt:
> +  case Instruction::FPTrunc:
> +  case Instruction::FPExt:
> +  case Instruction::UIToFP:
> +  case Instruction::SIToFP:
> +  case Instruction::FPToUI:
> +  case Instruction::FPToSI:
> +  case Instruction::PtrToInt:
> +  case Instruction::IntToPtr:
> +  case Instruction::BitCast:
> +    return CastInst::Create((Instruction::CastOps)getOpcode(),
> +                            Ops[0], getType());
> +  case Instruction::Select:
> +    return SelectInst::Create(Ops[0], Ops[1], Ops[2]);
> +  case Instruction::InsertElement:
> +    return InsertElementInst::Create(Ops[0], Ops[1], Ops[2]);
> +  case Instruction::ExtractElement:
> +    return ExtractElementInst::Create(Ops[0], Ops[1]);
> +  case Instruction::InsertValue:
> +    return InsertValueInst::Create(Ops[0], Ops[1], getIndices());
> +  case Instruction::ExtractValue:
> +    return ExtractValueInst::Create(Ops[0], getIndices());
> +  case Instruction::ShuffleVector:
> +    return new ShuffleVectorInst(Ops[0], Ops[1], Ops[2]);
> +
> +  case Instruction::GetElementPtr:
> +    if (cast<GEPOperator>(this)->isInBounds())
> +      return GetElementPtrInst::CreateInBounds(Ops[0], Ops.slice(1));
> +    else
> +      return GetElementPtrInst::Create(Ops[0], Ops.slice(1));
> +
> +  case Instruction::ICmp:
> +  case Instruction::FCmp:
> +    return CmpInst::Create((Instruction::OtherOps)getOpcode(),
> +                           getPredicate(), Ops[0], Ops[1]);
> +
> +  default:
> +    assert(getNumOperands() == 2 && "Must be binary operator?");
> +    BinaryOperator *BO =
> +      BinaryOperator::Create((Instruction::BinaryOps)getOpcode(),
> +                             Ops[0], Ops[1]);
> +    if (isa<OverflowingBinaryOperator>(BO)) {
> +      BO->setHasNoUnsignedWrap(SubclassOptionalData &
> +                               OverflowingBinaryOperator::NoUnsignedWrap);
> +      BO->setHasNoSignedWrap(SubclassOptionalData &
> +                             OverflowingBinaryOperator::NoSignedWrap);
> +    }
> +    if (isa<PossiblyExactOperator>(BO))
> +      BO->setIsExact(SubclassOptionalData & PossiblyExactOperator::IsExact);
> +    return BO;
> +  }
> +}
> 
> Modified: llvm/trunk/unittests/VMCore/ConstantsTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/VMCore/ConstantsTest.cpp?rev=168262&r1=168261&r2=168262&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/VMCore/ConstantsTest.cpp (original)
> +++ llvm/trunk/unittests/VMCore/ConstantsTest.cpp Sat Nov 17 11:56:30 2012
> @@ -8,8 +8,11 @@
> //===----------------------------------------------------------------------===//
> 
> #include "llvm/Constants.h"
> +#include "llvm/Instruction.h"
> +#include "llvm/InstrTypes.h"
> #include "llvm/DerivedTypes.h"
> #include "llvm/LLVMContext.h"
> +#include "llvm/Module.h"
> #include "gtest/gtest.h"
> 
> namespace llvm {
> @@ -118,5 +121,108 @@
>   EXPECT_TRUE(isa<ConstantFP>(X));
> }
> 
> +#define CHECK(x, y) {                                           \
> +    std::string __s;                                            \
> +    raw_string_ostream __o(__s);                                \
> +    cast<ConstantExpr>(x)->getAsInstruction()->print(__o);      \
> +    __o.flush();                                                \
> +    EXPECT_EQ(std::string("  <badref> = " y), __s);             \
> +  }
> +
> +TEST(ConstantsTest, AsInstructionsTest) {
> +  Module *M = new Module("MyModule", getGlobalContext());
> +
> +  Type *Int64Ty = Type::getInt64Ty(getGlobalContext());
> +  Type *Int32Ty = Type::getInt32Ty(getGlobalContext());
> +  Type *Int16Ty = Type::getInt16Ty(getGlobalContext());
> +  Type *Int1Ty = Type::getInt1Ty(getGlobalContext());
> +  Type *FloatTy = Type::getFloatTy(getGlobalContext());
> +  Type *DoubleTy = Type::getDoubleTy(getGlobalContext());
> +
> +  Constant *Global = M->getOrInsertGlobal("dummy",
> +                                         PointerType::getUnqual(Int32Ty));
> +  Constant *Global2 = M->getOrInsertGlobal("dummy2",
> +                                         PointerType::getUnqual(Int32Ty));
> +
> +  Constant *P0 = ConstantExpr::getPtrToInt(Global, Int32Ty);
> +  Constant *P1 = ConstantExpr::getUIToFP(P0, FloatTy);
> +  Constant *P2 = ConstantExpr::getUIToFP(P0, DoubleTy);
> +  Constant *P3 = ConstantExpr::getTrunc(P0, Int1Ty);
> +  Constant *P4 = ConstantExpr::getPtrToInt(Global2, Int32Ty);
> +  Constant *P5 = ConstantExpr::getUIToFP(P4, FloatTy);
> +  Constant *P6 = ConstantExpr::getBitCast(P4, VectorType::get(Int16Ty, 2));
> +
> +  Constant *One = ConstantInt::get(Int32Ty, 1);
> +
> +  #define P0STR "ptrtoint (i32** @dummy to i32)"
> +  #define P1STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to float)"
> +  #define P2STR "uitofp (i32 ptrtoint (i32** @dummy to i32) to double)"
> +  #define P3STR "ptrtoint (i32** @dummy to i1)"
> +  #define P4STR "ptrtoint (i32** @dummy2 to i32)"
> +  #define P5STR "uitofp (i32 ptrtoint (i32** @dummy2 to i32) to float)"
> +  #define P6STR "bitcast (i32 ptrtoint (i32** @dummy2 to i32) to <2 x i16>)"
> +
> +  CHECK(ConstantExpr::getNeg(P0), "sub i32 0, " P0STR);
> +  CHECK(ConstantExpr::getFNeg(P1), "fsub float -0.000000e+00, " P1STR);
> +  CHECK(ConstantExpr::getNot(P0), "xor i32 " P0STR ", -1");
> +  CHECK(ConstantExpr::getAdd(P0, P0), "add i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getAdd(P0, P0, false, true), "add nsw i32 " P0STR ", "
> +        P0STR);
> +  CHECK(ConstantExpr::getAdd(P0, P0, true, true), "add nuw nsw i32 " P0STR ", "
> +        P0STR);
> +  CHECK(ConstantExpr::getFAdd(P1, P1), "fadd float " P1STR ", " P1STR);
> +  CHECK(ConstantExpr::getSub(P0, P0), "sub i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getFSub(P1, P1), "fsub float " P1STR ", " P1STR);
> +  CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getFMul(P1, P1), "fmul float " P1STR ", " P1STR);
> +  CHECK(ConstantExpr::getUDiv(P0, P0), "udiv i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getFDiv(P1, P1), "fdiv float " P1STR ", " P1STR);
> +  CHECK(ConstantExpr::getURem(P0, P0), "urem i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getSRem(P0, P0), "srem i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getFRem(P1, P1), "frem float " P1STR ", " P1STR);
> +  CHECK(ConstantExpr::getAnd(P0, P0), "and i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getOr(P0, P0), "or i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getXor(P0, P0), "xor i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getShl(P0, P0), "shl i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getShl(P0, P0, true), "shl nuw i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getShl(P0, P0, false, true), "shl nsw i32 " P0STR ", "
> +        P0STR);
> +  CHECK(ConstantExpr::getLShr(P0, P0, false), "lshr i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getLShr(P0, P0, true), "lshr exact i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getAShr(P0, P0, false), "ashr i32 " P0STR ", " P0STR);
> +  CHECK(ConstantExpr::getAShr(P0, P0, true), "ashr exact i32 " P0STR ", " P0STR);
> +
> +  CHECK(ConstantExpr::getSExt(P0, Int64Ty), "sext i32 " P0STR " to i64");
> +  CHECK(ConstantExpr::getZExt(P0, Int64Ty), "zext i32 " P0STR " to i64");
> +  CHECK(ConstantExpr::getFPTrunc(P2, FloatTy), "fptrunc double " P2STR
> +        " to float");
> +  CHECK(ConstantExpr::getFPExtend(P1, DoubleTy), "fpext float " P1STR
> +        " to double");
> +
> +  CHECK(ConstantExpr::getExactUDiv(P0, P0), "udiv exact i32 " P0STR ", " P0STR);
> +
> +  CHECK(ConstantExpr::getSelect(P3, P0, P4), "select i1 " P3STR ", i32 " P0STR
> +        ", i32 " P4STR);
> +  CHECK(ConstantExpr::getICmp(CmpInst::ICMP_EQ, P0, P4), "icmp eq i32 " P0STR
> +        ", " P4STR);
> +  CHECK(ConstantExpr::getFCmp(CmpInst::FCMP_ULT, P1, P5), "fcmp ult float "
> +        P1STR ", " P5STR);
> +
> +  std::vector<Constant*> V;
> +  V.push_back(One);
> +  // FIXME: getGetElementPtr() actually creates an inbounds ConstantGEP,
> +  //        not a normal one!
> +  //CHECK(ConstantExpr::getGetElementPtr(Global, V, false),
> +  //      "getelementptr i32** @dummy, i32 1");
> +  CHECK(ConstantExpr::getInBoundsGetElementPtr(Global, V),
> +        "getelementptr inbounds i32** @dummy, i32 1");
> +
> +  CHECK(ConstantExpr::getExtractElement(P6, One), "extractelement <2 x i16> "
> +        P6STR ", i32 1");
> +}
> +
> +#undef CHECK
> +
> }  // end anonymous namespace
> }  // end namespace llvm
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list