https://llvm.org/bugs/show_bug.cgi?id=28224

            Bug ID: 28224
           Summary: [Regression] GVN optimization pass since llvm 3.8
                    produces wrong IR in one case
           Product: libraries
           Version: 3.8
          Hardware: Other
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Scalar Optimizations
          Assignee: unassignedb...@nondot.org
          Reporter: l...@joakim.fea.st
                CC: llvm-bugs@lists.llvm.org
    Classification: Unclassified

Created attachment 16605
  --> https://llvm.org/bugs/attachment.cgi?id=16605&action=edit
default optimization with inlining enabled

This bug was hit when using the ldc compiler frontend for the D programming
language with llvm 3.8.  It is not reproducible with llvm 3.7.1, so the problem
seems to have been introduced with 3.8.0, and persists with 3.9 master
svn-271934.

The following reduced test case was taken from the tests for the D standard
library:

import std.conv, std.array;

unittest
{
    auto r = toChars!(16)(16u);
    assert(r.length == 2);
    assert(r[1..2].array == "0");
}

When compiled with "ldc2 -unittest -O2 -main test.d", the last assert trips up.
 Removing the first assert or disabling inlining makes the second assert pass
again.  I've attached the IR generated for the test by ldc linked against llvm
3.7.1 and llvm 3.8.0 at -O3, which corresponds to llvm::CodeGenOpt::Aggressive
with inlining enabled, and llvm 3.8.0 at -O1 -enable-inlining, which
corresponds to llvm::CodegenOpt::Default with inlining enabled.

Here is the relevant portion that's wrong, along with the ldc command used to
produce the IR.

./build-llvm-3.8/bin/ldc2 -unittest -O3 -c test.d --output-ll
-of=llvm-3.8-O3.ll

bounds.ok.i:                                      ; preds =
%_D3std4conv47__T7toCharsVii16TaVE3std5ascii10LetterCasei1TkZ7toCharsFNaNbNiNfkZS3std4conv47__T7toCharsVii16TaVE3std5ascii10LetterCasei1TkZ7toCharsFNaNbNiNfkZ6Result.exit
  %5 = tail call i8*
@_D4core6memory2GC6mallocFNaNbkkxC8TypeInfoZPv(%object.TypeInfo* null, i32 2,
i32 1) ; [#uses = 2]
  %6 = insertvalue { i32, i8* } { i32 1, i8* undef }, i8* %5, 1 ; [#uses = 1]
  store i8 -1, i8* %5, align 1
  %7 = tail call i32 @_adEq2({ i32, i8* } %6, { i32, i8* } { i32 1, i8*
getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0) },
%object.TypeInfo* nonnull @_D11TypeInfo_Aa6__initZ) #3 ; [#uses = 1]
  %8 = icmp eq i32 %7, 0                          ; [#uses = 1]
  br i1 %8, label %assertFailed2, label %assertPassed1

Here's the same block from llvm 3.7.1.

./build-llvm-3.7/bin/ldc2 -unittest -O3 -c test.d --output-ll
-of=llvm-3.7-O3.ll

bounds.ok.i:
  %0 = tail call i8*
@_D4core6memory2GC6mallocFNaNbkkxC8TypeInfoZPv(%object.TypeInfo* null, i32 2,
i32 1) ; [#uses = 2]                     %1 = insertvalue { i32, i8* } { i32 1,
i8* undef }, i8* %0, 1 ; [#uses = 1]
  store i8 48, i8* %0, align 1
  %2 = tail call i32 @_adEq2({ i32, i8* } %1, { i32, i8* } { i32 1, i8*
getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0) },
%object.TypeInfo* nonnull @_D11TypeInfo_Aa6__initZ) #3 ; [#uses = 1]
  %3 = icmp eq i32 %2, 0                          ; [#uses = 1]        br i1
%3, label %assertFailed2, label %assertPassed1

Clearly the problem is that the "store i8 48" (where 48 is the ASCII value for
"0" from the test) in the second IR has been incorrectly replaced by "store i8
-1" in the first IR.  Using -print-after-all shows that the problematic
optimization is "Global Value Numbering" and disabling that pass in llvm 3.8.0
fixes the problem.

Let me know if any more info is necessary.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to