Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions tslang/include/TypeScript/LowerToLLVM/LLVMCodeHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,15 @@ class LLVMCodeHelper : public LLVMCodeHelperBase
DenseElementsAttr denseAttr;
if (isDense)
{
auto vectorType = mlir::VectorType::get({static_cast<int64_t>(value.size())}, llvmElementType);
dataType = vectorType;
// A vector of elements narrower than a byte (a boolean's i1) is packed into bits, but
// array elements are read one byte apart: `[false, true]` read back as garbage. Such
// data is an array, laid out a byte per element, like the elements it is copied to.
auto shapeSize = static_cast<int64_t>(value.size());
auto packedIntoBits = llvmElementType.isInteger() && llvmElementType.getIntOrFloatBitWidth() % 8 != 0;
mlir::ShapedType shapedType = packedIntoBits
? (mlir::ShapedType)mlir::RankedTensorType::get({shapeSize}, llvmElementType)
: (mlir::ShapedType)mlir::VectorType::get({shapeSize}, llvmElementType);
dataType = packedIntoBits ? arrayType : (mlir::Type)shapedType;

if (llvmElementType.isIntOrIndex())
{
Expand All @@ -585,7 +592,7 @@ class LLVMCodeHelper : public LLVMCodeHelperBase
values.push_back(cast<mlir::IntegerAttr>(value_).getValue());
});

denseAttr = DenseElementsAttr::get(vectorType, values);
denseAttr = DenseElementsAttr::get(shapedType, values);
}
else
{
Expand All @@ -594,7 +601,7 @@ class LLVMCodeHelper : public LLVMCodeHelperBase
values.push_back(cast<mlir::FloatAttr>(value_).getValue());
});

denseAttr = DenseElementsAttr::get(vectorType, values);
denseAttr = DenseElementsAttr::get(shapedType, values);
}
}

Expand Down
3 changes: 3 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ tslang_add_test(NAME test-compile-01-enums COMMAND test-runner "${PROJECT_SOURCE
tslang_add_test(NAME test-compile-00-numbers COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00numbers.ts")
tslang_add_test(NAME test-compile-00-equals COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00equals.ts")
tslang_add_test(NAME test-compile-00-bool-arith-ops COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00bool_arith_ops.ts")
tslang_add_test(NAME test-compile-00-bool-const-array COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00bool_const_array.ts")
tslang_add_test(NAME test-compile-00-mixed-type-ops COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00mixed_type_ops.ts")
tslang_add_test(NAME test-compile-00-generator-manual-next COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00generator_manual_next.ts")
tslang_add_test(NAME test-compile-00-generator-manual-next-2 COMMAND test-runner "${PROJECT_SOURCE_DIR}/test/tester/tests/00generator_manual_next2.ts")
Expand Down Expand Up @@ -791,6 +792,7 @@ tslang_add_test(NAME test-jit-01-enums COMMAND test-runner -jit "${PROJECT_SOURC
tslang_add_test(NAME test-jit-00-numbers COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00numbers.ts")
tslang_add_test(NAME test-jit-00-equals COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00equals.ts")
tslang_add_test(NAME test-jit-00-bool-arith-ops COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00bool_arith_ops.ts")
tslang_add_test(NAME test-jit-00-bool-const-array COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00bool_const_array.ts")
tslang_add_test(NAME test-jit-00-mixed-type-ops COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00mixed_type_ops.ts")
tslang_add_test(NAME test-jit-00-generator-manual-next COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00generator_manual_next.ts")
tslang_add_test(NAME test-jit-00-generator-manual-next-2 COMMAND test-runner -jit "${PROJECT_SOURCE_DIR}/test/tester/tests/00generator_manual_next2.ts")
Expand Down Expand Up @@ -1745,6 +1747,7 @@ set(TSLANG_CORPUS
00async_gc_threading.ts
00async_result_types.ts
00bool_arith_ops.ts
00bool_const_array.ts
00break_continue_scope_exit.ts
00break_continue.ts
00capture_in_new_arguments.ts
Expand Down
53 changes: 53 additions & 0 deletions tslang/test/tester/tests/00bool_const_array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// The elements of a boolean array literal read back wrong: the constant data was an LLVM vector of
// i1, which packs its elements into bits, while elements are read one byte apart. So `if (F[i])`
// was never taken, a count of the true elements came out as 10 for four elements, and F[1] was
// false.

const FLAGS = [false, true, false, true];

function countTrue(flags: boolean[]) {
let n = 0;
for (let i = 0; i < flags.length; i++) {
if (flags[i]) {
n++;
}
}

return n;
}

function locals() {
let a = [true, false, true];
assert(a[0], "a[0]");
assert(!a[1], "a[1]");
assert(a[2], "a[2]");

let n = 0;
for (const x of a) {
if (x) n++;
}

assert(n == 2, "for-of count");
}

function many() {
// more elements than fit in a byte of bits
const m = [true, false, false, true, true, false, true, false, true, true, false, true];
assert(countTrue(m) == 7, "twelve elements");
assert(m[11], "m[11]");
assert(!m[10], "m[10]");
}

function main() {
assert(FLAGS.length == 4, "length");
assert(countTrue(FLAGS) == 2, "count");
const b: boolean = FLAGS[1];
assert(b, "FLAGS[1]");
assert(!FLAGS[0], "FLAGS[0]");
assert(FLAGS[3], "FLAGS[3]");

locals();
many();

print("done.");
}
Loading