Add a new Constant::getIntegerValue helper function, and convert a
authorDan Gohman <gohman@apple.com>
Mon, 3 Aug 2009 22:07:33 +0000 (22:07 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 3 Aug 2009 22:07:33 +0000 (22:07 +0000)
few places in InstCombine to use it, to fix problems handling pointer
types. This fixes the recent llvm-gcc bootstrap error.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78005 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Constant.h
lib/Transforms/Scalar/InstructionCombining.cpp
lib/VMCore/Constants.cpp
test/Transforms/InstCombine/simplify-demanded-bits-pointer.ll [new file with mode: 0644]

index 3b3089748e0b75bfedec032e08ca7de27a4a4201..a42c7d43717116b50845870050d7735d4d160ea1 100644 (file)
@@ -17,6 +17,8 @@
 #include "llvm/User.h"
 
 namespace llvm {
+  class APInt;
+
   template<typename T> class SmallVectorImpl;
   class LLVMContext;
 
@@ -142,6 +144,10 @@ public:
   /// its bits set to true.
   /// @brief Get the all ones value
   static Constant* getAllOnesValue(const Type* Ty);
+
+  /// getIntegerValue - Return the value for an integer or pointer constant,
+  /// or a vector thereof, with the given scalar value.
+  static Constant* getIntegerValue(const Type* Ty, const APInt &V);
 };
 
 } // End llvm namespace
index 4d2248e291788640f8146a8b7847d4bf1c7c02e7..b9b4ccb6cfb82a66fabec4cab970357cac7acc48 100644 (file)
@@ -1014,8 +1014,8 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) { 
       // all known
       if ((RHSKnownOne & LHSKnownOne) == RHSKnownOne) {
-        Constant *AndC = ConstantInt::get(VTy, 
-                                          ~RHSKnownOne & DemandedMask);
+        Constant *AndC = Constant::getIntegerValue(VTy,
+                                                   ~RHSKnownOne & DemandedMask);
         Instruction *And = 
           BinaryOperator::CreateAnd(I->getOperand(0), AndC, "tmp");
         return InsertNewInstBefore(And, *I);
@@ -1406,12 +1406,8 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
   
   // If the client is only demanding bits that we know, return the known
   // constant.
-  if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) {
-    Constant *C = ConstantInt::get(VTy, RHSKnownOne);
-    if (isa<PointerType>(V->getType()))
-      C = ConstantExpr::getIntToPtr(C, V->getType());
-    return C;
-  }
+  if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask)
+    return Constant::getIntegerValue(VTy, RHSKnownOne);
   return false;
 }
 
index 7482154d839561f17dc7638e2272821091360b10..e02e28a87ee4b198baa53cca451d45365cec1d08 100644 (file)
@@ -70,6 +70,23 @@ Constant* Constant::getNullValue(const Type* Ty) {
   }
 }
 
+Constant* Constant::getIntegerValue(const Type* Ty, const APInt &V) {
+  const Type *ScalarTy = Ty->getScalarType();
+
+  // Create the base integer constant.
+  Constant *C = ConstantInt::get(Ty->getContext(), V);
+
+  // Convert an integer to a pointer, if necessary.
+  if (const PointerType *PTy = dyn_cast<PointerType>(ScalarTy))
+    C = ConstantExpr::getIntToPtr(C, PTy);
+
+  // Broadcast a scalar to a vector, if necessary.
+  if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
+    C = ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
+
+  return C;
+}
+
 Constant* Constant::getAllOnesValue(const Type* Ty) {
   if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
     return ConstantInt::get(Ty->getContext(),
diff --git a/test/Transforms/InstCombine/simplify-demanded-bits-pointer.ll b/test/Transforms/InstCombine/simplify-demanded-bits-pointer.ll
new file mode 100644 (file)
index 0000000..d399799
--- /dev/null
@@ -0,0 +1,84 @@
+; RUN: llvm-as < %s | opt -instcombine
+
+; SimplifyDemandedBits should cope with pointer types.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+       %struct.VEC_rtx_base = type { i32, i32, [1 x %struct.rtx_def*] }
+       %struct.VEC_rtx_gc = type { %struct.VEC_rtx_base }
+       %struct.block_symbol = type { [3 x %struct.rtunion], %struct.object_block*, i64 }
+       %struct.object_block = type { %struct.section*, i32, i64, %struct.VEC_rtx_gc*, %struct.VEC_rtx_gc* }
+       %struct.omp_clause_subcode = type { i32 }
+       %struct.rtunion = type { i8* }
+       %struct.rtx_def = type { i16, i8, i8, %struct.u }
+       %struct.section = type { %struct.unnamed_section }
+       %struct.u = type { %struct.block_symbol }
+       %struct.unnamed_section = type { %struct.omp_clause_subcode, void (i8*)*, i8*, %struct.section* }
+
+define fastcc void @cse_insn(%struct.rtx_def* %insn, %struct.rtx_def* %libcall_insn) nounwind {
+entry:
+       br i1 undef, label %bb43, label %bb88
+
+bb43:          ; preds = %entry
+       br label %bb88
+
+bb88:          ; preds = %bb43, %entry
+       br i1 undef, label %bb95, label %bb107
+
+bb95:          ; preds = %bb88
+       unreachable
+
+bb107:         ; preds = %bb88
+       %0 = load i16* undef, align 8           ; <i16> [#uses=1]
+       %1 = icmp eq i16 %0, 38         ; <i1> [#uses=1]
+       %src_eqv_here.0 = select i1 %1, %struct.rtx_def* null, %struct.rtx_def* null            ; <%struct.rtx_def*> [#uses=1]
+       br i1 undef, label %bb127, label %bb125
+
+bb125:         ; preds = %bb107
+       br i1 undef, label %bb127, label %bb126
+
+bb126:         ; preds = %bb125
+       br i1 undef, label %bb129, label %bb133
+
+bb127:         ; preds = %bb125, %bb107
+       unreachable
+
+bb129:         ; preds = %bb126
+       br label %bb133
+
+bb133:         ; preds = %bb129, %bb126
+       br i1 undef, label %bb134, label %bb146
+
+bb134:         ; preds = %bb133
+       unreachable
+
+bb146:         ; preds = %bb133
+       br i1 undef, label %bb180, label %bb186
+
+bb180:         ; preds = %bb146
+       %2 = icmp eq %struct.rtx_def* null, null                ; <i1> [#uses=1]
+       %3 = zext i1 %2 to i8           ; <i8> [#uses=1]
+       %4 = icmp ne %struct.rtx_def* %src_eqv_here.0, null             ; <i1> [#uses=1]
+       %5 = zext i1 %4 to i8           ; <i8> [#uses=1]
+       %toBool181 = icmp ne i8 %3, 0           ; <i1> [#uses=1]
+       %toBool182 = icmp ne i8 %5, 0           ; <i1> [#uses=1]
+       %6 = and i1 %toBool181, %toBool182              ; <i1> [#uses=1]
+       %7 = zext i1 %6 to i8           ; <i8> [#uses=1]
+       %toBool183 = icmp ne i8 %7, 0           ; <i1> [#uses=1]
+       br i1 %toBool183, label %bb184, label %bb186
+
+bb184:         ; preds = %bb180
+       br i1 undef, label %bb185, label %bb186
+
+bb185:         ; preds = %bb184
+       br label %bb186
+
+bb186:         ; preds = %bb185, %bb184, %bb180, %bb146
+       br i1 undef, label %bb190, label %bb195
+
+bb190:         ; preds = %bb186
+       unreachable
+
+bb195:         ; preds = %bb186
+       unreachable
+}