Fix SDISel lowering of zeroinitializer and undef to use ComputeValueVTs.
authorDan Gohman <gohman@apple.com>
Mon, 4 Aug 2008 23:30:41 +0000 (23:30 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 4 Aug 2008 23:30:41 +0000 (23:30 +0000)
This allows it to work correctly on nested aggregate values.
This fixes PR2625.

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

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
test/CodeGen/Generic/pr2625.ll [new file with mode: 0644]

index ef90400023c5117990af51f80952129678e93830..1e8afe81032ff30ffc4dd7811f9cb01fb177cc3c 100644 (file)
@@ -1184,34 +1184,18 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
       return DAG.getMergeValues(&Constants[0], Constants.size());
     }
 
-    if (const ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) {
+    if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType())) {
       assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
-             "Unknown array constant!");
-      unsigned NumElts = ATy->getNumElements();
-      if (NumElts == 0)
-        return SDValue(); // empty array
-      MVT EltVT = TLI.getValueType(ATy->getElementType());
-      SmallVector<SDValue, 4> Constants(NumElts);
-      for (unsigned i = 0, e = NumElts; i != e; ++i) {
-        if (isa<UndefValue>(C))
-          Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
-        else if (EltVT.isFloatingPoint())
-          Constants[i] = DAG.getConstantFP(0, EltVT);
-        else
-          Constants[i] = DAG.getConstant(0, EltVT);
-      }
-      return DAG.getMergeValues(&Constants[0], Constants.size());
-    }
+             "Unknown struct or array constant!");
 
-    if (const StructType *STy = dyn_cast<StructType>(C->getType())) {
-      assert((isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) &&
-             "Unknown struct constant!");
-      unsigned NumElts = STy->getNumElements();
+      SmallVector<MVT, 4> ValueVTs;
+      ComputeValueVTs(TLI, C->getType(), ValueVTs);
+      unsigned NumElts = ValueVTs.size();
       if (NumElts == 0)
         return SDValue(); // empty struct
       SmallVector<SDValue, 4> Constants(NumElts);
-      for (unsigned i = 0, e = NumElts; i != e; ++i) {
-        MVT EltVT = TLI.getValueType(STy->getElementType(i));
+      for (unsigned i = 0; i != NumElts; ++i) {
+        MVT EltVT = ValueVTs[i];
         if (isa<UndefValue>(C))
           Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
         else if (EltVT.isFloatingPoint())
@@ -1219,7 +1203,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
         else
           Constants[i] = DAG.getConstant(0, EltVT);
       }
-      return DAG.getMergeValues(&Constants[0], Constants.size());
+      return DAG.getMergeValues(&Constants[0], NumElts);
     }
 
     const VectorType *VecTy = cast<VectorType>(V->getType());
diff --git a/test/CodeGen/Generic/pr2625.ll b/test/CodeGen/Generic/pr2625.ll
new file mode 100644 (file)
index 0000000..c1f585d
--- /dev/null
@@ -0,0 +1,17 @@
+; RUN: llvm-as < %s | llc
+; PR2625
+
+define i32 @main({ i32, { i32 } }*) {
+entry:
+        %state = alloca { i32, { i32 } }*               ; <{ i32, { i32 } }**> [#uses=2]
+        store { i32, { i32 } }* %0, { i32, { i32 } }** %state
+        %retval = alloca i32            ; <i32*> [#uses=2]
+        store i32 0, i32* %retval
+        load { i32, { i32 } }** %state          ; <{ i32, { i32 } }*>:1 [#uses=1]
+        store { i32, { i32 } } zeroinitializer, { i32, { i32 } }* %1
+        br label %return
+
+return:         ; preds = %entry
+        load i32* %retval               ; <i32>:2 [#uses=1]
+        ret i32 %2
+}