[pkg-d-commits] [ldc] 16/74: toconstelem: Implement array literal VectorExps

Matthias Klumpp mak at moszumanska.debian.org
Thu Jul 13 20:54:14 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.3.0-beta2
in repository ldc.

commit c26bfcbdaa796bc9136b93ca74311ab13d0c121a
Author: David Nadlinger <code at klickverbot.at>
Date:   Sun May 7 02:00:08 2017 +0100

    toconstelem: Implement array literal VectorExps
    
    Previously, we would always try to splat the given expression across the
    whole vector. This hasn't been noticed earlier as DMD mostly generates
    ArrayInitializers when initializing vectors to array literals (but
    notably not when explicitly assigning VectorType.init).
    
    GitHub: Fixes #2101.
---
 gen/toconstelem.cpp         | 41 ++++++++++++++++++++++++++++-------------
 tests/codegen/vector_init.d | 20 ++++++++++++++++++++
 2 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/gen/toconstelem.cpp b/gen/toconstelem.cpp
index 1d37db6..adec650 100644
--- a/gen/toconstelem.cpp
+++ b/gen/toconstelem.cpp
@@ -702,20 +702,35 @@ public:
     TypeVector *tv = static_cast<TypeVector *>(e->to->toBasetype());
     assert(tv->ty == Tvector);
 
-    // The AST for
-    //   static immutable ubyte16 vec1 = 123;
-    // differs from
-    //    static immutable ubyte[16] vec1 = 123;
-    // In the vector case the AST contains an IntegerExp (of type int) and a
-    // CastExp to type ubyte. In the static array case the AST only contains an
-    // IntegerExp of type ubyte. Simply call optimize to get  rid of the cast.
-    // FIXME: Check DMD source to understand why two different ASTs are
-    //        constructed.
-    llvm::Constant *val = toConstElem(e->e1->optimize(WANTvalue));
-
-    dinteger_t elemCount =
+    const auto elemCount =
         static_cast<TypeSArray *>(tv->basetype)->dim->toInteger();
-    result = llvm::ConstantVector::getSplat(elemCount, val);
+
+    // Array literals are assigned element-for-element; other expressions splat
+    // across the whole vector.
+    if (e->e1->op == TOKarrayliteral) {
+      const auto ale = static_cast<ArrayLiteralExp *>(e->e1);
+
+      llvm::SmallVector<llvm::Constant *, 16> elements;
+      elements.reserve(elemCount);
+      for (size_t i = 0; i < elemCount; ++i) {
+        elements.push_back(toConstElem(indexArrayLiteral(ale, i)));
+      }
+
+      result = llvm::ConstantVector::get(elements);
+    } else {
+      // The AST for
+      //   static immutable ubyte16 vec1 = 123;
+      // differs from
+      //    static immutable ubyte[16] vec1 = 123;
+      // In the vector case the AST contains an IntegerExp (of type int) and a
+      // CastExp to type ubyte. In the static array case the AST only contains
+      // an IntegerExp of type ubyte. Simply call optimize to get rid of the
+      // cast.
+      // FIXME: Check DMD source to understand why two different ASTs are
+      //        constructed.
+      result = llvm::ConstantVector::getSplat(
+          elemCount, toConstElem(e->e1->optimize(WANTvalue)));
+    }
   }
 
   //////////////////////////////////////////////////////////////////////////////
diff --git a/tests/codegen/vector_init.d b/tests/codegen/vector_init.d
new file mode 100644
index 0000000..6254bf7
--- /dev/null
+++ b/tests/codegen/vector_init.d
@@ -0,0 +1,20 @@
+// Make sure vector initializer llvm::Constants are generated correctly (GitHub #2101).
+// RUN: %ldc -c -O3 -output-ll -of=%t.ll %s && FileCheck %s < %t.ll
+
+alias D2 = __vector(double[2]);
+
+// CHECK: @_D11vector_init12ImplicitInit6__initZ =
+// CHECK-SAME: { <2 x double> <double 0x7FFC000000000000, double 0x7FFC000000000000> }
+struct ImplicitInit { D2 a; }
+
+// CHECK: @_D11vector_init12ExplicitInit6__initZ =
+// CHECK-SAME: { <2 x double> <double 0x7FFC000000000000, double 0x7FFC000000000000> }
+struct ExplicitInit { D2 a = D2.init; }
+
+// CHECK: @_D11vector_init10SplatValue6__initZ =
+// CHECK-SAME: { <2 x double> <double 1.000000e+00, double 1.000000e+00> }
+struct SplatValue { D2 a = 1.0; }
+
+// CHECK: @_D11vector_init13ElementValues6__initZ =
+// CHECK-SAME: { <2 x double> <double 1.000000e+00, double 2.000000e+00> }
+struct ElementValues { D2 a = [1.0, 2.0]; }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list