mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-15 07:33:18 +00:00
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
72c84a8294
commit
46456f6a2f
@ -93,9 +93,12 @@ bool ConstantMerge::hasKnownAlignment(GlobalVariable *GV) const {
|
||||
}
|
||||
|
||||
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 &M) {
|
||||
// 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.
|
||||
|
28
test/Transforms/ConstantMerge/align.ll
Normal file
28
test/Transforms/ConstantMerge/align.ll
Normal file
@ -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
|
||||
@T1A = internal unnamed_addr constant i32 1
|
||||
@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.
|
||||
@T2A = internal unnamed_addr constant i32 2, align 1
|
||||
@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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user