[llvm] r194506 - Corruptly merge constants with explicit and implicit alignments.

Rafael Espindola rafael.espindola at gmail.com
Tue Nov 12 12:21:43 PST 2013


Author: rafael
Date: Tue Nov 12 14:21:43 2013
New Revision: 194506

URL: http://llvm.org/viewvc/llvm-project?rev=194506&view=rev
Log:
Corruptly merge constants with explicit and implicit alignments.

Constant merge can merge a constant with implicit alignment with one that has
explicit alignment. Before this change it was assuming that the explicit
alignment was higher than the implicit one, causing the result to be under
aligned in some cases.

Fixes pr17815.

Patch by Chris Smowton!

Added:
    llvm/trunk/test/Transforms/ConstantMerge/align.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp

Modified: llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp?rev=194506&r1=194505&r2=194506&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ConstantMerge.cpp Tue Nov 12 14:21:43 2013
@@ -93,9 +93,12 @@ bool ConstantMerge::hasKnownAlignment(Gl
 }
 
 unsigned ConstantMerge::getAlignment(GlobalVariable *GV) const {
+  unsigned Align = GV->getAlignment();
+  if (Align)
+    return Align;
   if (TD)
     return TD->getPreferredAlignment(GV);
-  return GV->getAlignment();
+  return 0;
 }
 
 bool ConstantMerge::runOnModule(Module &M) {
@@ -210,9 +213,9 @@ bool ConstantMerge::runOnModule(Module &
       // Bump the alignment if necessary.
       if (Replacements[i].first->getAlignment() ||
           Replacements[i].second->getAlignment()) {
-        Replacements[i].second->setAlignment(std::max(
-            Replacements[i].first->getAlignment(),
-            Replacements[i].second->getAlignment()));
+        Replacements[i].second->setAlignment(
+            std::max(getAlignment(Replacements[i].first),
+                     getAlignment(Replacements[i].second)));
       }
 
       // Eliminate any uses of the dead global.

Added: llvm/trunk/test/Transforms/ConstantMerge/align.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstantMerge/align.ll?rev=194506&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ConstantMerge/align.ll (added)
+++ llvm/trunk/test/Transforms/ConstantMerge/align.ll Tue Nov 12 14:21:43 2013
@@ -0,0 +1,28 @@
+; RUN: opt -constmerge -S < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+
+; Test that with a TD we do merge and mark the alignment as 4
+ at T1A = internal unnamed_addr constant i32 1
+ at T1B = internal unnamed_addr constant i32 1, align 2
+; CHECK: @T1B = internal unnamed_addr constant i32 1, align 4
+
+define void @test1(i32** %P1, i32** %P2) {
+  store i32* @T1A, i32** %P1
+  store i32* @T1B, i32** %P2
+  ret void
+}
+
+
+; Test that even with a TD we set the alignment to the maximum if both constants
+; have explicit alignments.
+ at T2A = internal unnamed_addr constant i32 2, align 1
+ at T2B = internal unnamed_addr constant i32 2, align 2
+; CHECK: @T2B = internal unnamed_addr constant i32 2, align 2
+
+define void @test2(i32** %P1, i32** %P2) {
+  store i32* @T2A, i32** %P1
+  store i32* @T2B, i32** %P2
+  ret void
+}





More information about the llvm-commits mailing list