[PATCH] D55169: [ConstantFolding] Handle leading zero-length elements in load folding
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 1 14:25:14 PST 2018
nikic created this revision.
nikic added a reviewer: spatel.
Herald added subscribers: llvm-commits, JDevlieghere.
Struct types may have leading zero-length elements like `[0 x i32]`, in which case the "real" element at offset 0 will not necessarily coincide with the 0th element of the aggregate. `ConstantFoldLoadThroughBitcast()` wants to drill down the element at offset 0, but currently always picks the 0th aggregate element to do so. This patch changes the code to find the first non-zero-length element instead.
The motivation behind this change is https://github.com/rust-lang/rust/issues/48627. Rust is fond of emitting `[0 x iN]` separators between struct elements to enforce alignment, which prevents constant folding in this particular case.
Repository:
rL LLVM
https://reviews.llvm.org/D55169
Files:
lib/Analysis/ConstantFolding.cpp
test/Transforms/ConstProp/loads.ll
Index: test/Transforms/ConstProp/loads.ll
===================================================================
--- test/Transforms/ConstProp/loads.ll
+++ test/Transforms/ConstProp/loads.ll
@@ -269,3 +269,16 @@
; BE-LABEL: @test16.3(
; BE: ret i64 0
}
+
+ at g7 = constant {[0 x i32], [0 x i8], i64} { [0 x i32] undef, [0 x i8] undef, i64 123 }
+
+define i64 @test_leading_zero_size_elems() {
+ %v = load i64, i64* bitcast ({[0 x i32], [0 x i8], i64}* @g7 to i64*)
+ ret i64 %v
+
+; LE-LABEL: @test_leading_zero_size_elems(
+; LE: ret i64 123
+
+; BE-LABEL: @test_leading_zero_size_elems(
+; BE: ret i64 123
+}
Index: lib/Analysis/ConstantFolding.cpp
===================================================================
--- lib/Analysis/ConstantFolding.cpp
+++ lib/Analysis/ConstantFolding.cpp
@@ -347,9 +347,16 @@
// We're simulating a load through a pointer that was bitcast to point to
// a different type, so we can try to walk down through the initial
- // elements of an aggregate to see if some part of th e aggregate is
+ // elements of an aggregate to see if some part of the aggregate is
// castable to implement the "load" semantic model.
- C = C->getAggregateElement(0u);
+ unsigned Elem = 0;
+ Constant *ElemC;
+ do {
+ ElemC = C->getAggregateElement(Elem++);
+ // Structs might have leading zero-length elements like [0 x i32], which
+ // are certainly not what we are looking for, so skip them.
+ } while (ElemC && DL.getTypeSizeInBits(ElemC->getType()) == 0);
+ C = ElemC;
} while (C);
return nullptr;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55169.176269.patch
Type: text/x-patch
Size: 1581 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181201/7fd2b3fd/attachment.bin>
More information about the llvm-commits
mailing list