Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimizer bug on ind2sub #7197

Closed
tanmaykm opened this issue Jun 10, 2014 · 20 comments
Closed

optimizer bug on ind2sub #7197

tanmaykm opened this issue Jun 10, 2014 · 20 comments
Labels
bug Indicates an unexpected problem or unintended behavior
Milestone

Comments

@tanmaykm
Copy link
Member

julia> let S = [1 2 3; 4 5 6; 7 8 9]
           println(ind2sub(size(S), 5));
           @test S[1] == 1
       end
(1,2)

This is incorrect. Surprisingly, not using @test gives the correct result:

julia> let S = [1 2 3; 4 5 6; 7 8 9]
                  println(ind2sub(size(S), 5));
              end
(2,2)

I'm on:

julia> versioninfo()
Julia Version 0.3.0-prerelease+3609
Commit 664cab5* (2014-06-10 05:18 UTC)
Platform Info:
  System: Darwin (x86_64-apple-darwin13.2.0)
  CPU: Intel(R) Core(TM)2 Duo CPU     P7550  @ 2.26GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY)
  LAPACK: libopenblas
  LIBM: libopenlibm
mauro3 added a commit to mauro3/julia that referenced this issue Jun 10, 2014
This PR does:
- fix a bug in getindex_general.  Indexing with a disordered
  array lead to a no-methods error. Test added
- temprary fix for JuliaLang#7197 in `test/sparse.jl`
- added performance tests for Sparse-uint matrices
@mauro3
Copy link
Contributor

mauro3 commented Jun 10, 2014

Seems to be a problem with the let-block. Running

 begin
       S = [1 2 3; 4 5 6; 7 8 9]
       println(ind2sub(size(S), 5));
       @test S[1] == 1
end

works. Thus work around for sparse-test in above PR.

mauro3 added a commit to mauro3/julia that referenced this issue Jun 10, 2014
This PR does:
- fix a bug in getindex_general.  Indexing with a disordered
  array lead to a no-methods error. Test added
- temprary fix for JuliaLang#7197 in `test/sparse.jl`
- added performance tests for Sparse-uint matrices
@JeffBezanson
Copy link
Sponsor Member

Reduced case:

function foo()
  S = [1 2 3; 4 5 6; 7 8 9]
  ind2sub(size(S), 5)
end

julia> foo()
(1,2)

Even worse, turning off LLVM optimizations fixes it.
The unoptimized code contains:

oksrem:                                           ; preds = %pass
  %60 = srem i64 4, %56, !dbg !789
  br label %after_srem, !dbg !789

after_srem:                                       ; preds = %oksrem, %minus1
  %61 = phi i64 [ 0, %minus1 ], [ %60, %oksrem ], !dbg !789
  %62 = add i64 %61, 1, !dbg !789

and the optimizer changes this to

oksrem:                                           ; preds = %top
  %26 = srem i64 4, %24, !dbg !1609
  %phitmp3 = or i64 %26, 1, !dbg !1609
  br label %after_srem, !dbg !1609

after_srem:                                       ; preds = %top, %oksrem
  %27 = phi i64 [ %phitmp3, %oksrem ], [ 1, %top ]

It looks like add 1 was replaced with or 1.

@JeffBezanson JeffBezanson changed the title Strange ind2sub behavior when used with @test optimizer bug on ind2sub Jun 10, 2014
@Keno
Copy link
Member

Keno commented Jun 12, 2014

Seems to work fine on LLVM 3.5

@ViralBShah
Copy link
Member

What do we do for the 0.3 release?

@ViralBShah ViralBShah added this to the 0.3 milestone Jun 12, 2014
@Keno
Copy link
Member

Keno commented Jun 12, 2014

One of,

  1. Bisect, see what fixed it and backport the fix
  2. Switch to 3.5
  3. Live with it
    .

@Keno
Copy link
Member

Keno commented Jun 12, 2014

Of course there's still the issue of distributions including vanilla 3.3

@ViralBShah
Copy link
Member

Is it possible that a particular optimizer pass is doing it, and we can disable it?

@JeffBezanson
Copy link
Sponsor Member

Found it. Here's the llvm commit that fixed it:

diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 8add1ea..a7bfe09 100644
--- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -754,7 +754,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
       ComputeMaskedBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth+1);
       // If it's known zero, our sign bit is also zero.
       if (LHSKnownZero.isNegative())
-        KnownZero |= LHSKnownZero;
+        KnownZero.setBit(KnownZero.getBitWidth() - 1);
     }
     break;
   case Instruction::URem: {

I'm inclined to include this patch.

The culprit is the InstructionCombining pass. We could remove all uses of it when not using our own llvm; the performance difference seems to be fairly small.

@ViralBShah
Copy link
Member

Cc: @ArchRobison

@ViralBShah
Copy link
Member

Do we just use USE_SYSTEM_LLVM setting in the Makefile to detect if we are using our patched LLVM?

@ivarne
Copy link
Sponsor Member

ivarne commented Jun 19, 2014

Will that patch actually be applied for people that just git pull && make? Wouldn't it be better to patch a LLVM header file to indicate that the patch has been applied?

@nalimilan
Copy link
Member

I'm not going to be able to fix the system LLVM in Fedora, so if you want this to be fixed in distro packages it would be good to find a workaround in Julia until it is ported to LLVM 3.5.

@JeffBezanson
Copy link
Sponsor Member

Yes I am just using USE_SYSTEM_LLVM here.

We do have a workaround; certain optimization passes can be disabled. However the patch currently causes a mysterious test failure on travis.

@ArchRobison
Copy link
Contributor

I like the suggestion of patching an LLVM header file with a #define that says the bug is fixed. There are likely to be more of these issues in the future and it's nice to have one place that lists all the bug switches.

JeffBezanson added a commit that referenced this issue Jun 19, 2014
fix #7197, backport a fix to SimplifyDemandedUseBits in LLVM
@StefanKarpinski
Copy link
Sponsor Member

So does this require a make -C deps clean-llvm or something?

@JeffBezanson
Copy link
Sponsor Member

I find the following works with minimal rebuild time:

cd deps
patch -p0 < instcombine-llvm-3.3.patch
rm -rf ../usr/lib/libLLVM*
make install-llvm

@StefanKarpinski
Copy link
Sponsor Member

For the record, the clean-llvm thing worked too but took a while.

@timholy
Copy link
Sponsor Member

timholy commented Jun 21, 2014

Jeff's practice of tagging new tests with their issue numbers is awesome. In this case, it helped me answer "why doesn't Julia pass its tests, and how do I fix it?" in 30s flat.

@StefanKarpinski
Copy link
Sponsor Member

That is a really effective and useful practice.

@tkelman
Copy link
Contributor

tkelman commented Jun 22, 2014

@ihnorton this test is failing in the Windows binaries, can you make sure the LLVM patch gets applied next rebuild? cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests