[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