<div dir="ltr"><div>Hi All,<br><br></div>Please find enclosed a patch to avoid constant folding through empty type fields. Previously, ConstantFoldLoadThroughGEPIndices and ConstantFoldLoadThroughGEPConstantExpr would return zeroinitializer when a constant GEP expression indexed to a zero-length field. The patch adds checks to these two methods based on isEmptyTy to avoid these scenarios. The patch also includes a simple testcase. I have verified that the testcase fails with r216246 and passes after applying the patch.<br>


<div class="gmail_quote">
<br></div><div class="gmail_quote">Tom<br></div><div class="gmail_quote"><br>
<a href="http://reviews.llvm.org/D5032" target="_blank">http://reviews.llvm.org/D5032</a><br>
<br>
Files:<br>
  lib/Analysis/ConstantFolding.cpp<br>
  test/Transforms/GlobalOpt/empty-type-field.ll<br>
<br>
Index: lib/Analysis/ConstantFolding.cpp<br>
===================================================================<br>
--- lib/Analysis/ConstantFolding.cpp<br>
+++ lib/Analysis/ConstantFolding.cpp<br>
@@ -1206,6 +1206,10 @@<br>
     C = C->getAggregateElement(CE->getOperand(i));<br>
     if (!C)<br>
       return nullptr;<br>
+<br>
+    // Don't step through empty types. The aliasing is too hard to figure out.<br>
+    if (C->getType()->isEmptyTy())<br>
+      return nullptr;<br>
   }<br>
   return C;<br>
 }<br>
@@ -1222,6 +1226,10 @@<br>
     C = C->getAggregateElement(Indices[i]);<br>
     if (!C)<br>
       return nullptr;<br>
+<br>
+    // Don't step through empty types. The aliasing is too hard to figure out.<br>
+    if (C->getType()->isEmptyTy())<br>
+      return nullptr;<br>
   }<br>
   return C;<br>
 }<br>
Index: test/Transforms/GlobalOpt/empty-type-field.ll<br>
===================================================================<br>
--- test/Transforms/GlobalOpt/empty-type-field.ll<br>
+++ test/Transforms/GlobalOpt/empty-type-field.ll<br>
@@ -0,0 +1,19 @@<br>
+; RUN: opt < %s -S -globalopt | FileCheck %s<br>
+<br>
+; ModuleID = 'bugpoint-passinput.bc'<br>
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-unknown-linux-gnu"<br>
+<br>
+%struct.qux = type { [0 x double], double }<br>
+<br>
+@qux = internal global %struct.qux { [0 x double] zeroinitializer, double 4.053854e+04 }, align 8<br>
+<br>
+define void @foo() {<br>
+entry:<br>
+  %0 = load double* getelementptr inbounds (%struct.qux* @qux, i32 0, i32 0, i32 0), align 1<br>
+  call void @bar(double %0)<br>
+; CHECK-NOT: @bar(double 0.000000e+00)<br>
+  ret void<br>
+}<br>
+<br>
+declare void @bar(double)<br>
\ No newline at end of file<br>
</div><br></div>