Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-04 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---

Comment(by scpmw):

 I can't simply attach what crashed for me because it requires a number of
 additional GHC patches to reproduce - all of which are ''very''
 experimental at this stage. I will have another go at reproducing it, the
 incomplete test case probably just needs one of the normally-saved
 registers to be live across r to fail.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:6
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-04 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---

Comment(by scpmw):

 Okay, seems you are indeed right. Once registers are actually live, they
 get saved and the code does what it should.

 The root cause here was my GHC tinkering, which happened to generate
 primitive calls without paying attention to live variables - which is in
 itself perfectly safe except that LLVM codegen counts on this unnecessary
 register saving taking place in order to produce correct code. Whew,
 didn't expect that.

 Apologies for the confusion. I guess this can be closed, as the upsides
 have now been reduced to
 just less redundant code getting generated.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:7
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-04 Thread GHC
#4992: LLVM trashes registers for primitive calls
--+-
  Reporter:  scpmw|  Owner:  davidterei@…
  Type:  bug  | Status:  closed  
  Priority:  normal   |  Milestone:  
 Component:  Compiler (LLVM)  |Version:  7.1 
Resolution:  invalid  |   Keywords:  
  Testcase:   |  Blockedby:  
Difficulty:   | Os:  Linux   
  Blocking:   |   Architecture:  x86_64 (amd64)  
   Failure:  Runtime crash|  
--+-
Changes (by dterei):

  * status:  patch = closed
  * resolution:  = invalid


Comment:

 Cool! I wouldn't say that not paying attention to live variables is
 perfectly safe though. The native code generator as I understand also
 relies on this saving and restoring of live registers to have already been
 done in the Cmm representation. The only reason it didn't crash on the
 same code I assume is that the code for the primitive call never touched
 the live registers. Its perfectly legal for it to do so though, so there
 are some cases with bigger primitive calls where it would fail for the
 native code generator. LLVM failed earlier as the registers are trashed to
 prevent code duplication and slowdown and as there was no save and restore
 in the Cmm LLVM correctly used the actually live registers for
 intermediate code in the function.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:8
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-03 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---

Comment(by dterei):

 Is it not possible for you to simply attach the original program that
 crashes without the patch? If its private code you could just share it
 with me via email if you would prefer. I am not 100% convinced this patch
 solves the root of the problem.

 Across C calls (regardless of prim or not) the registers are trashed
 because GHC has previously generated code to save and restore the
 appropriate registers. In the Cmm code given to the LLVM backend
 spill/reload of the R3... registers already exists and so to have LLVM do
 it as well just duplicates work. Thats why the backend simply trashes all
 the caller save registers blindly. This isn't the best solution but it
 shouldn't cause any bugs.

 e.g so if R3 is live across a call you should see code like:

 {{{
 %lnXe = load i64* %R3_Var
 store i64 %ln1zX, i64* %ln1zZ
 store i64 undef, i64* %R3_Var
 store i64 undef, i64* %R4_Var
 store i64 undef, i64* %R5_Var
 store i64 undef, i64* %R6_Var
 store float undef, float* %F1_Var
 store float undef, float* %F2_Var
 store float undef, float* %F3_Var
 store float undef, float* %F4_Var
 store double undef, double* %D1_Var
 store double undef, double* %D2_Var
 %ln1A0 = call ccc double (double)* @tan( double 0x3FE0 )
 nounwind
 store i64 %lnXe, i64* %R3_Var
 }}}

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:5
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-02 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---

Comment(by scpmw):

 Producing a test case for isn't straightforward... It would have to
 construct a situation where LLVM is pressured for (non-floating-point)
 registers while at the same time making heavy use of LLVM primitives. At
 the moment, these all concern floating-point operations, which makes this
 hard. Using round, for example, makes the code pieces end up in
 different thunks. I suppose that's the reason why this problem hasn't
 shown up so far.

 It might be possible to come up with something by addressing the primops
 directly and using unsafeCoerce in order to force GHC to pull some ints
 out of nowhere... But I'm not really sure the testcase would even be
 useful at that point.

 The problem surfaced for me when I tried to add a primop for querying the
 cycle counter (llvm.readcyclecounter), which always uses two integer
 registers and therefore quickly ends up overwriting important stuff.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:3
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-02 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---

Comment(by scpmw):

 I have attached my best shot at reproducing the problem with just tan.
 It generates roughly the following code before the patch:

 {{{
 subq$72, %rsp
 movq%r15, 40(%rsp)  # 8-byte Spill
 movq%r14, 32(%rsp)  # 8-byte Spill
 movq%r12, 24(%rsp)  # 8-byte Spill
 movq%rbp, 8(%rsp)   # 8-byte Spill
 movq%r13, 16(%rsp)  # 8-byte Spill
 movaps  %xmm5, %xmm0
 callq   tan
 cvttsd2siq  %xmm0, %rax
 movq%rax, 56(%rsp)  # 8-byte Spill
 }}}

 And then goes on using all available registers, which is clearly
 dangerous. With the patch applied, a lot more registers are saved on top
 of the stack.

 I'm unsure though how to craft an actually failing program out of this.
 Maybe somebody with a better overview can put in the missing piece?

 (Fun fact: The program actually manages to crash the LLVM optimizer both
 with and without the patch. Compiling without -O works.)

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:4
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


[GHC] #4992: LLVM trashes registers for primitive calls

2011-03-01 Thread GHC
#4992: LLVM trashes registers for primitive calls
---+
Reporter:  scpmw   |   Owner:  davidterei@…
Type:  bug |  Status:  new 
Priority:  normal  |   Component:  Compiler (LLVM) 
 Version:  7.1 |Keywords:  
Testcase:  |   Blockedby:  
  Os:  Linux   |Blocking:  
Architecture:  x86_64 (amd64)  | Failure:  Runtime crash   
---+
 When calling, the LLVM backend will generate code that sets a number
 of global registers to undefined to prevent LLVM from saving them. I
 suppose that's a good idea for C calls, but for primitive calls it is
 unnecessary, even dangerous. tan 0.5 will have the backend generate code
 like follows:

 {{{
 ...
 store i64 %ln1zX, i64* %ln1zZ
 store i64 undef, i64* %R3_Var
 store i64 undef, i64* %R4_Var
 store i64 undef, i64* %R5_Var
 store i64 undef, i64* %R6_Var
 store float undef, float* %F1_Var
 store float undef, float* %F2_Var
 store float undef, float* %F3_Var
 store float undef, float* %F4_Var
 store double undef, double* %D1_Var
 store double undef, double* %D2_Var
 %ln1A0 = call ccc double (double)* @tan( double 0x3FE0 )
 nounwind
 ...
 }}}

 A few lines later, these registers are then read again, with LLVM
 probably assuming that the read results don't matter, as it can deduce
 that tan can't have written them.

 I discovered this when investigating why my programs using additional
 primitive operations kept crashing. Removing the trashing for
 primitive calls seems to fix the problem nicely, patch attached.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-01 Thread GHC
#4992: LLVM trashes registers for primitive calls
---+
Reporter:  scpmw   |   Owner:  davidterei@…
Type:  bug |  Status:  new 
Priority:  normal  |   Component:  Compiler (LLVM) 
 Version:  7.1 |Keywords:  
Testcase:  |   Blockedby:  
  Os:  Linux   |Blocking:  
Architecture:  x86_64 (amd64)  | Failure:  Runtime crash   
---+

Comment(by dterei):

 Looks good. Could you please attach a test case though.

-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:1
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


Re: [GHC] #4992: LLVM trashes registers for primitive calls

2011-03-01 Thread GHC
#4992: LLVM trashes registers for primitive calls
+---
Reporter:  scpmw|Owner:  davidterei@…
Type:  bug  |   Status:  patch   
Priority:  normal   |Milestone:  
   Component:  Compiler (LLVM)  |  Version:  7.1 
Keywords:   | Testcase:  
   Blockedby:   |   Difficulty:  
  Os:  Linux| Blocking:  
Architecture:  x86_64 (amd64)   |  Failure:  Runtime crash   
+---
Changes (by igloo):

  * status:  new = patch


-- 
Ticket URL: http://hackage.haskell.org/trac/ghc/ticket/4992#comment:2
GHC http://www.haskell.org/ghc/
The Glasgow Haskell Compiler

___
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs