Generalize a few more instcombines to be vector/scalar-independent.
authorDan Gohman <gohman@apple.com>
Tue, 16 Jun 2009 19:55:29 +0000 (19:55 +0000)
committerDan Gohman <gohman@apple.com>
Tue, 16 Jun 2009 19:55:29 +0000 (19:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73541 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/vector-casts-0.ll [new file with mode: 0644]
test/Transforms/InstCombine/vector-casts-1.ll [new file with mode: 0644]
test/Transforms/InstCombine/vector-casts.ll [deleted file]

index d77c2b5fc481dc9e87db6cc15077c1f2b9bb0678..8dc8659648f0f446a75521eedea4f5cf68675573 100644 (file)
@@ -5967,9 +5967,9 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
 
   unsigned BitWidth = 0;
   if (TD)
-    BitWidth = TD->getTypeSizeInBits(Ty);
-  else if (isa<IntegerType>(Ty))
-    BitWidth = Ty->getPrimitiveSizeInBits();
+    BitWidth = TD->getTypeSizeInBits(Ty->getScalarType());
+  else if (Ty->isIntOrIntVector())
+    BitWidth = Ty->getScalarSizeInBits();
 
   bool isSignBit = false;
 
@@ -7234,18 +7234,16 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) {
   if (ConstantInt *CSI = dyn_cast<ConstantInt>(Op0))
     if (CSI->isAllOnesValue())
       return ReplaceInstUsesWith(I, CSI);
-  
+
   // See if we can turn a signed shr into an unsigned shr.
-  if (!isa<VectorType>(I.getType())) {
-    if (MaskedValueIsZero(Op0,
-                      APInt::getSignBit(I.getType()->getPrimitiveSizeInBits())))
-      return BinaryOperator::CreateLShr(Op0, I.getOperand(1));
-
-    // Arithmetic shifting an all-sign-bit value is a no-op.
-    unsigned NumSignBits = ComputeNumSignBits(Op0);
-    if (NumSignBits == Op0->getType()->getPrimitiveSizeInBits())
-      return ReplaceInstUsesWith(I, Op0);
-  }
+  if (MaskedValueIsZero(Op0,
+                        APInt::getSignBit(I.getType()->getScalarSizeInBits())))
+    return BinaryOperator::CreateLShr(Op0, I.getOperand(1));
+
+  // Arithmetic shifting an all-sign-bit value is a no-op.
+  unsigned NumSignBits = ComputeNumSignBits(Op0);
+  if (NumSignBits == Op0->getType()->getScalarSizeInBits())
+    return ReplaceInstUsesWith(I, Op0);
 
   return 0;
 }
@@ -7295,7 +7293,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
 
   // See if we can simplify any instructions used by the instruction whose sole 
   // purpose is to compute bits we don't care about.
-  uint32_t TypeBits = Op0->getType()->getPrimitiveSizeInBits();
+  uint32_t TypeBits = Op0->getType()->getScalarSizeInBits();
   
   // shl i32 X, 32 = 0 and srl i8 Y, 9 = 0, ... just don't eliminate
   // a signed shift.
@@ -7344,8 +7342,8 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
       // part of the register be zeros.  Emulate this by inserting an AND to
       // clear the top bits as needed.  This 'and' will usually be zapped by
       // other xforms later if dead.
-      unsigned SrcSize = TrOp->getType()->getPrimitiveSizeInBits();
-      unsigned DstSize = TI->getType()->getPrimitiveSizeInBits();
+      unsigned SrcSize = TrOp->getType()->getScalarSizeInBits();
+      unsigned DstSize = TI->getType()->getScalarSizeInBits();
       APInt MaskV(APInt::getLowBitsSet(SrcSize, DstSize));
       
       // The mask we constructed says what the trunc would do if occurring
@@ -8380,7 +8378,8 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
   uint32_t SrcBitWidth = Src->getType()->getScalarSizeInBits();
 
   // Canonicalize trunc x to i1 -> (icmp ne (and x, 1), 0)
-  if (!isa<VectorType>(Ty) && DestBitWidth == 1) {
+  if (DestBitWidth == 1 &&
+      isa<VectorType>(Ty) == isa<VectorType>(Src->getType())) {
     Constant *One = ConstantInt::get(Src->getType(), 1);
     Src = InsertNewInstBefore(BinaryOperator::CreateAnd(Src, One, "tmp"), CI);
     Value *Zero = Constant::getNullValue(Src->getType());
diff --git a/test/Transforms/InstCombine/vector-casts-0.ll b/test/Transforms/InstCombine/vector-casts-0.ll
new file mode 100644 (file)
index 0000000..ae5b8a9
--- /dev/null
@@ -0,0 +1,55 @@
+; RUN: llvm-as < %s | opt -instcombine
+
+define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind {
+entry:
+       %val = trunc <2 x i64> %src to <2 x i32>                ; <<2 x i32>> [#uses=1]
+       %add = add <2 x i32> %val, <i32 1, i32 1>               ; <<2 x i32>> [#uses=1]
+       store <2 x i32> %add, <2 x i32>* %dst.addr
+       ret void
+}
+
+define <2 x i65> @foo(<2 x i64> %t) {
+  %a = trunc <2 x i64> %t to <2 x i32>
+  %b = zext <2 x i32> %a to <2 x i65>
+  ret <2 x i65> %b
+}
+define <2 x i64> @bar(<2 x i65> %t) {
+  %a = trunc <2 x i65> %t to <2 x i32>
+  %b = zext <2 x i32> %a to <2 x i64>
+  ret <2 x i64> %b
+}
+define <2 x i65> @foos(<2 x i64> %t) {
+  %a = trunc <2 x i64> %t to <2 x i32>
+  %b = sext <2 x i32> %a to <2 x i65>
+  ret <2 x i65> %b
+}
+define <2 x i64> @bars(<2 x i65> %t) {
+  %a = trunc <2 x i65> %t to <2 x i32>
+  %b = sext <2 x i32> %a to <2 x i64>
+  ret <2 x i64> %b
+}
+define <2 x i64> @quxs(<2 x i64> %t) {
+  %a = trunc <2 x i64> %t to <2 x i32>
+  %b = sext <2 x i32> %a to <2 x i64>
+  ret <2 x i64> %b
+}
+define <2 x i64> @quxt(<2 x i64> %t) {
+  %a = shl <2 x i64> %t, <i64 32, i64 32>
+  %b = ashr <2 x i64> %a, <i64 32, i64 32>
+  ret <2 x i64> %b
+}
+define <2 x double> @fa(<2 x double> %t) {
+  %a = fptrunc <2 x double> %t to <2 x float>
+  %b = fpext <2 x float> %a to <2 x double>
+  ret <2 x double> %b
+}
+define <2 x double> @fb(<2 x double> %t) {
+  %a = fptoui <2 x double> %t to <2 x i64>
+  %b = uitofp <2 x i64> %a to <2 x double>
+  ret <2 x double> %b
+}
+define <2 x double> @fc(<2 x double> %t) {
+  %a = fptosi <2 x double> %t to <2 x i64>
+  %b = sitofp <2 x i64> %a to <2 x double>
+  ret <2 x double> %b
+}
diff --git a/test/Transforms/InstCombine/vector-casts-1.ll b/test/Transforms/InstCombine/vector-casts-1.ll
new file mode 100644 (file)
index 0000000..a73a84a
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | opt -instcombine > %t
+; RUN: not grep trunc %t
+; RUN: not grep ashr %t
+
+; This turns into a&1 != 0
+define <2 x i1> @a(<2 x i64> %a) {
+  %t = trunc <2 x i64> %a to <2 x i1>
+  ret <2 x i1> %t
+}
+; The ashr turns into an lshr.
+define <2 x i64> @b(<2 x i64> %a) {
+  %b = and <2 x i64> %a, <i64 65535, i64 65535>
+  %t = ashr <2 x i64> %b, <i64 1, i64 1>
+  ret <2 x i64> %t
+}
diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll
deleted file mode 100644 (file)
index ae5b8a9..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-; RUN: llvm-as < %s | opt -instcombine
-
-define void @convert(<2 x i32>* %dst.addr, <2 x i64> %src) nounwind {
-entry:
-       %val = trunc <2 x i64> %src to <2 x i32>                ; <<2 x i32>> [#uses=1]
-       %add = add <2 x i32> %val, <i32 1, i32 1>               ; <<2 x i32>> [#uses=1]
-       store <2 x i32> %add, <2 x i32>* %dst.addr
-       ret void
-}
-
-define <2 x i65> @foo(<2 x i64> %t) {
-  %a = trunc <2 x i64> %t to <2 x i32>
-  %b = zext <2 x i32> %a to <2 x i65>
-  ret <2 x i65> %b
-}
-define <2 x i64> @bar(<2 x i65> %t) {
-  %a = trunc <2 x i65> %t to <2 x i32>
-  %b = zext <2 x i32> %a to <2 x i64>
-  ret <2 x i64> %b
-}
-define <2 x i65> @foos(<2 x i64> %t) {
-  %a = trunc <2 x i64> %t to <2 x i32>
-  %b = sext <2 x i32> %a to <2 x i65>
-  ret <2 x i65> %b
-}
-define <2 x i64> @bars(<2 x i65> %t) {
-  %a = trunc <2 x i65> %t to <2 x i32>
-  %b = sext <2 x i32> %a to <2 x i64>
-  ret <2 x i64> %b
-}
-define <2 x i64> @quxs(<2 x i64> %t) {
-  %a = trunc <2 x i64> %t to <2 x i32>
-  %b = sext <2 x i32> %a to <2 x i64>
-  ret <2 x i64> %b
-}
-define <2 x i64> @quxt(<2 x i64> %t) {
-  %a = shl <2 x i64> %t, <i64 32, i64 32>
-  %b = ashr <2 x i64> %a, <i64 32, i64 32>
-  ret <2 x i64> %b
-}
-define <2 x double> @fa(<2 x double> %t) {
-  %a = fptrunc <2 x double> %t to <2 x float>
-  %b = fpext <2 x float> %a to <2 x double>
-  ret <2 x double> %b
-}
-define <2 x double> @fb(<2 x double> %t) {
-  %a = fptoui <2 x double> %t to <2 x i64>
-  %b = uitofp <2 x i64> %a to <2 x double>
-  ret <2 x double> %b
-}
-define <2 x double> @fc(<2 x double> %t) {
-  %a = fptosi <2 x double> %t to <2 x i64>
-  %b = sitofp <2 x i64> %a to <2 x double>
-  ret <2 x double> %b
-}