OSDN Git Service

[GVN] Fold constant expression in GVN.
authorEkaterina Romanova <katya_romanova@playstation.sony.com>
Thu, 14 Jul 2016 22:02:25 +0000 (22:02 +0000)
committerEkaterina Romanova <katya_romanova@playstation.sony.com>
Thu, 14 Jul 2016 22:02:25 +0000 (22:02 +0000)
Fix for PR 28418.

opt never finishes compiling a test when -gvn option is passed.
The problem is caused by the fact that GVN fails to fold a constant expression.

Differential Revision: https://reviews.llvm.org/D22185

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

lib/Transforms/Scalar/GVN.cpp
test/Transforms/GVN/fold-const-expr.ll [new file with mode: 0644]

index a963b2f..a35a106 100644 (file)
@@ -725,6 +725,9 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
   assert(CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, DL) &&
          "precondition violation - materialization can't fail");
 
+  if (auto *CExpr = dyn_cast<ConstantExpr>(StoredVal))
+    StoredVal = ConstantFoldConstantExpression(CExpr, DL);
+
   // If this is already the right type, just return it.
   Type *StoredValTy = StoredVal->getType();
 
@@ -735,25 +738,29 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
   if (StoredValSize == LoadedValSize) {
     // Pointer to Pointer -> use bitcast.
     if (StoredValTy->getScalarType()->isPointerTy() &&
-        LoadedTy->getScalarType()->isPointerTy())
-      return IRB.CreateBitCast(StoredVal, LoadedTy);
+        LoadedTy->getScalarType()->isPointerTy()) {
+      StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy);
+    } else {
+      // Convert source pointers to integers, which can be bitcast.
+      if (StoredValTy->getScalarType()->isPointerTy()) {
+        StoredValTy = DL.getIntPtrType(StoredValTy);
+        StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy);
+      }
 
-    // Convert source pointers to integers, which can be bitcast.
-    if (StoredValTy->getScalarType()->isPointerTy()) {
-      StoredValTy = DL.getIntPtrType(StoredValTy);
-      StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy);
-    }
+      Type *TypeToCastTo = LoadedTy;
+      if (TypeToCastTo->getScalarType()->isPointerTy())
+        TypeToCastTo = DL.getIntPtrType(TypeToCastTo);
 
-    Type *TypeToCastTo = LoadedTy;
-    if (TypeToCastTo->getScalarType()->isPointerTy())
-      TypeToCastTo = DL.getIntPtrType(TypeToCastTo);
+      if (StoredValTy != TypeToCastTo)
+        StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo);
 
-    if (StoredValTy != TypeToCastTo)
-      StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo);
+      // Cast to pointer if the load needs a pointer type.
+      if (LoadedTy->getScalarType()->isPointerTy())
+        StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy);
+    }
 
-    // Cast to pointer if the load needs a pointer type.
-    if (LoadedTy->getScalarType()->isPointerTy())
-      StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy);
+    if (auto *CExpr = dyn_cast<ConstantExpr>(StoredVal))
+      StoredVal = ConstantFoldConstantExpression(CExpr, DL);
 
     return StoredVal;
   }
@@ -788,15 +795,19 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
   Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadedValSize);
   StoredVal  = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc");
 
-  if (LoadedTy == NewIntTy)
-    return StoredVal;
+  if (LoadedTy != NewIntTy) {
+    // If the result is a pointer, inttoptr.
+    if (LoadedTy->getScalarType()->isPointerTy())
+      StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr");
+    else
+      // Otherwise, bitcast.
+      StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast");
+  }
 
-  // If the result is a pointer, inttoptr.
-  if (LoadedTy->getScalarType()->isPointerTy())
-    return IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr");
+  if (auto *CExpr = dyn_cast<ConstantExpr>(StoredVal))
+    StoredVal = ConstantFoldConstantExpression(CExpr, DL);
 
-  // Otherwise, bitcast.
-  return IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast");
+  return StoredVal;
 }
 
 /// This function is called when we have a
diff --git a/test/Transforms/GVN/fold-const-expr.ll b/test/Transforms/GVN/fold-const-expr.ll
new file mode 100644 (file)
index 0000000..562f39c
--- /dev/null
@@ -0,0 +1,99 @@
+; GVN failed to do constant expression folding and expanded\r
+; them unfolded in many places, producing exponentially large const\r
+; expressions. As a result, the compilation never fisished.\r
+; This test checks that we are folding constant expression\r
+; PR 28418\r
+; RUN: opt -gvn -S < %s | FileCheck %s\r
+\r
+%2 = type { i32, i32, i32, i32, i32 }\r
+define i32 @_Z16vector3util_mainv(i32 %x, i32 %y)  {\r
+  %tmp1 = alloca %2, align 4\r
+  %tmp114 = getelementptr inbounds %2, %2* %tmp1, i64 0, i32 1\r
+  %tmp115 = bitcast i32* %tmp114 to <4 x i32>*\r
+  store <4 x i32> <i32 234567891, i32 345678912, i32 456789123, i32 0>, <4 x i32>* %tmp115, align 4\r
+  %tmp1683 = getelementptr inbounds %2, %2* %tmp1, i64 0, i32 1\r
+  %tmp1688 = load i32, i32* %tmp1683, align 4\r
+  %tmp1693 = shl i32 %tmp1688, 5\r
+  %tmp1694 = xor i32 %tmp1693, %tmp1688\r
+  %tmp1695 = lshr i32 %tmp1694, 7\r
+  %tmp1696 = xor i32 %tmp1695, %tmp1694\r
+  %tmp1697 = shl i32 %tmp1696, 22\r
+  %tmp1698 = xor i32 %tmp1697, %tmp1696\r
+  %tmp1707 = shl i32 %tmp1698, 5\r
+  %tmp1708 = xor i32 %tmp1707, %tmp1698\r
+  %tmp1709 = lshr i32 %tmp1708, 7\r
+  %tmp1710 = xor i32 %tmp1709, %tmp1708\r
+  %tmp1711 = shl i32 %tmp1710, 22\r
+  %tmp1712 = xor i32 %tmp1711, %tmp1710\r
+  %tmp1721 = shl i32 %tmp1712, 5\r
+  %tmp1722 = xor i32 %tmp1721, %tmp1712\r
+  %tmp1723 = lshr i32 %tmp1722, 7\r
+  %tmp1724 = xor i32 %tmp1723, %tmp1722\r
+  %tmp1725 = shl i32 %tmp1724, 22\r
+  %tmp1726 = xor i32 %tmp1725, %tmp1724\r
+  %tmp1735 = shl i32 %tmp1726, 5\r
+  %tmp1736 = xor i32 %tmp1735, %tmp1726\r
+  %tmp1737 = lshr i32 %tmp1736, 7\r
+  %tmp1738 = xor i32 %tmp1737, %tmp1736\r
+  %tmp1739 = shl i32 %tmp1738, 22\r
+  %tmp1740 = xor i32 %tmp1739, %tmp1738\r
+  store i32 %tmp1740, i32* %tmp1683, align 4\r
+; CHECK: store i32 310393545, i32* %tmp114, align 4\r
+  %tmp1756 = getelementptr inbounds %2, %2* %tmp1, i64 0, i32 1\r
+  %tmp1761 = load i32, i32* %tmp1756, align 4\r
+  %tmp1766 = shl i32 %tmp1761, 5\r
+  %tmp1767 = xor i32 %tmp1766, %tmp1761\r
+  %tmp1768 = lshr i32 %tmp1767, 7\r
+  %tmp1769 = xor i32 %tmp1768, %tmp1767\r
+  %tmp1770 = shl i32 %tmp1769, 22\r
+  %tmp1771 = xor i32 %tmp1770, %tmp1769\r
+  %tmp1780 = shl i32 %tmp1771, 5\r
+  %tmp1781 = xor i32 %tmp1780, %tmp1771\r
+  %tmp1782 = lshr i32 %tmp1781, 7\r
+  %tmp1783 = xor i32 %tmp1782, %tmp1781\r
+  %tmp1784 = shl i32 %tmp1783, 22\r
+  %tmp1785 = xor i32 %tmp1784, %tmp1783\r
+  %tmp1794 = shl i32 %tmp1785, 5\r
+  %tmp1795 = xor i32 %tmp1794, %tmp1785\r
+  %tmp1796 = lshr i32 %tmp1795, 7\r
+  %tmp1797 = xor i32 %tmp1796, %tmp1795\r
+  %tmp1798 = shl i32 %tmp1797, 22\r
+  %tmp1799 = xor i32 %tmp1798, %tmp1797\r
+  %tmp1808 = shl i32 %tmp1799, 5\r
+  %tmp1809 = xor i32 %tmp1808, %tmp1799\r
+  %tmp1810 = lshr i32 %tmp1809, 7\r
+  %tmp1811 = xor i32 %tmp1810, %tmp1809\r
+  %tmp1812 = shl i32 %tmp1811, 22\r
+  %tmp1813 = xor i32 %tmp1812, %tmp1811\r
+  store i32 %tmp1813, i32* %tmp1756, align 4\r
+; CHECK: store i32 -383584258, i32* %tmp114, align 4\r
+  %tmp2645 = getelementptr inbounds %2, %2* %tmp1, i64 0, i32 1\r
+  %tmp2650 = load i32, i32* %tmp2645, align 4\r
+  %tmp2655 = shl i32 %tmp2650, 5\r
+  %tmp2656 = xor i32 %tmp2655, %tmp2650\r
+  %tmp2657 = lshr i32 %tmp2656, 7\r
+  %tmp2658 = xor i32 %tmp2657, %tmp2656\r
+  %tmp2659 = shl i32 %tmp2658, 22\r
+  %tmp2660 = xor i32 %tmp2659, %tmp2658\r
+  %tmp2669 = shl i32 %tmp2660, 5\r
+  %tmp2670 = xor i32 %tmp2669, %tmp2660\r
+  %tmp2671 = lshr i32 %tmp2670, 7\r
+  %tmp2672 = xor i32 %tmp2671, %tmp2670\r
+  %tmp2673 = shl i32 %tmp2672, 22\r
+  %tmp2674 = xor i32 %tmp2673, %tmp2672\r
+  %tmp2683 = shl i32 %tmp2674, 5\r
+  %tmp2684 = xor i32 %tmp2683, %tmp2674\r
+  %tmp2685 = lshr i32 %tmp2684, 7\r
+  %tmp2686 = xor i32 %tmp2685, %tmp2684\r
+  %tmp2687 = shl i32 %tmp2686, 22\r
+  %tmp2688 = xor i32 %tmp2687, %tmp2686\r
+  %tmp2697 = shl i32 %tmp2688, 5\r
+  %tmp2698 = xor i32 %tmp2697, %tmp2688\r
+  %tmp2699 = lshr i32 %tmp2698, 7\r
+  %tmp2700 = xor i32 %tmp2699, %tmp2698\r
+  %tmp2701 = shl i32 %tmp2700, 22\r
+  %tmp2702 = xor i32 %tmp2701, %tmp2700\r
+  store i32 %tmp2702, i32* %tmp2645, align 4\r
+; CHECK: store i32 -57163022, i32* %tmp114, align 4\r
+  ret i32 0\r
+}\r