LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1023 - folding load of non-constant initializer
Summary: folding load of non-constant initializer
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Common Code Generator Code (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords: miscompilation
Depends on:
Blocks:
 
Reported: 2006-11-28 15:57 PST by Dan Gohman
Modified: 2010-02-22 12:47 PST (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Gohman 2006-11-28 15:57:23 PST
The logic that folds loads of static initializers doesn't take into account
whether the variable being initialized may be modified at runtime.

Here's a patch that fixes it:


Index: SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp,v
retrieving revision 1.319
diff -u -r1.319 SelectionDAGISel.cpp
--- SelectionDAGISel.cpp
+++ SelectionDAGISel.cpp
@@ -3298,7 +3298,7 @@
         }
         if (G) {
           GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getGlobal());
-          if (GV) {
+          if (GV && GV->isConstant()) {
             Str = GV->getStringValue(false);
             if (!Str.empty()) {
               CopyFromStr = true;



And here's a testcase that reproduces it:

target datalayout = "e-p:32:32"
target endian = little
target pointersize = 32
target triple = "i686-pc-linux-gnu"
%fmt = global [4 x sbyte] c"%x\0A\00"
%bytes = global [4 x sbyte] c"\AA\BB\CC\DD"

implementation

void %foo() {
        %y = alloca uint
        %c = cast uint* %y to sbyte*
        %z = getelementptr [4 x sbyte]* %bytes, int 0, int 0
        call void %llvm.memcpy.i32( sbyte* %c, sbyte* %z, uint 4, uint 1 )
        %r = load uint* %y
        %t = cast [4 x sbyte]* %fmt to sbyte*
        %tmp = call int (sbyte*, ...)* %printf( sbyte* %t, uint %r )
        ret void
}

declare void %llvm.memcpy.i32(sbyte*, sbyte*, uint, uint)

declare int %printf(sbyte*, ...)
Comment 1 Evan Cheng 2006-11-28 19:58:23 PST
Patch applied. Thanks!