bagel99 / llvm-my66000

This is a fork of the LLVM project. The code in branch my66000 supports Mitch Alsup's MY66000. The code in branch mcore supports the Motorola MCore.
http://llvm.org
Other
2 stars 2 forks source link

LLVM error: Cannot select with fma #18

Closed tkoenig1 closed 1 year ago

tkoenig1 commented 1 year ago

With the most recent version, with Perl.

tkoenig@gcc188:~/PERL/TST> cat sv.i
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
S_utf8_mg_pos_cache_update() {
  float keep_earlier = 0 + 0 * (float)mg_ptr_3;
  if (keep_earlier)
    S_utf8_mg_pos_cache_update_cache_3 = 0;
}
tkoenig@gcc188:~/PERL/TST> cat ~/bin/66
#! /bin/bash
a=${1%%.[ci]}
b=${a}_opt
clang -fverbose-asm -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops $1
opt  -disable-loop-unrolling -O3  --march=my66000 --frame-pointer=none --enable-vvm $a.bc  > $b.bc
llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $b.bc
tkoenig@gcc188:~/PERL/TST> 66 sv.i
sv.i:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
^
sv.i:1:11: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
          ^
sv.i:2:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
S_utf8_mg_pos_cache_update() {
^
sv.i:6:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
4 warnings generated.
LLVM ERROR: Cannot select: 0x6cc7760: f32 = fma 0x6cc7690, 0x6cc77c8, 0x6cc77c8
  0x6cc7690: f32 = sint_to_fp 0x6cc7898
    0x6cc7898: i64,ch = load<(dereferenceable load (s32) from @mg_ptr_3, !tbaa !2), sext from i32> 0x6c7f868, 0x6cc7b70, undef:i64
      0x6cc7b70: i64 = My66000ISD::WRAPPER TargetGlobalAddress:i64<i32* @mg_ptr_3> 0
        0x6cc76f8: i64 = TargetGlobalAddress<i32* @mg_ptr_3> 0
      0x6cc75c0: i64 = undef
  0x6cc77c8: f64 = My66000ISD::F32I5 Constant:i64<0>
    0x6cc7558: i64 = Constant<0>
  0x6cc77c8: f64 = My66000ISD::F32I5 Constant:i64<0>
    0x6cc7558: i64 = Constant<0>
In function: S_utf8_mg_pos_cache_update
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
Stack dump:
0.      Program arguments: llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 sv_opt.bc
1.      Running pass 'Function Pass Manager' on module 'sv_opt.bc'.
2.      Running pass 'My66000 DAG->DAG Pattern Instruction Selection' on function '@S_utf8_mg_pos_cache_update'
 #0 0x0000000002a61c0f PrintStackTraceSignalHandler(void*) Signals.cpp:0:0
 #1 0x0000000002a5f5a9 SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f584f5818c0 __restore_rt (/lib64/libpthread.so.0+0x168c0)
 #3 0x00007f584e3e2cbb raise (/lib64/libc.so.6+0x4acbb)
 #4 0x00007f584e3e4355 abort (/lib64/libc.so.6+0x4c355)
 #5 0x00000000029ade35 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/tkoenig/bin/llc+0x29ade35)
 #6 0x000000000288167b llvm::SelectionDAGISel::CannotYetSelect(llvm::SDNode*) (/home/tkoenig/bin/llc+0x288167b)
 #7 0x000000000288467d llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/home/tkoenig/bin/llc+0x288467d)
 #8 0x0000000001827ebd (anonymous namespace)::My66000DAGToDAGISel::Select(llvm::SDNode*) My66000ISelDAGToDAG.cpp:0:0
 #9 0x00000000028802d4 llvm::SelectionDAGISel::DoInstructionSelection() (/home/tkoenig/bin/llc+0x28802d4)
#10 0x0000000002887e76 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/home/tkoenig/bin/llc+0x2887e76)
#11 0x000000000288b42c llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/tkoenig/bin/llc+0x288b42c)
#12 0x000000000288d5c2 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.889) SelectionDAGISel.cpp:0:0
#13 0x0000000001ecb3a8 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/tkoenig/bin/llc+0x1ecb3a8)
#14 0x00000000022eed49 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/tkoenig/bin/llc+0x22eed49)
#15 0x00000000022eefe1 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/tkoenig/bin/llc+0x22eefe1)
#16 0x00000000022efa07 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/tkoenig/bin/llc+0x22efa07)
#17 0x00000000007dcd27 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#18 0x0000000000705ce2 main (/home/tkoenig/bin/llc+0x705ce2)
#19 0x00007f584e3cd29d __libc_start_main (/lib64/libc.so.6+0x3529d)
#20 0x00000000007d45ca _start /home/abuild/rpmbuild/BUILD/glibc-2.31/csu/../sysdeps/x86_64/start.S:122:0
/home/tkoenig/bin/66: Zeile 6: 15545 Abgebrochen             (Speicherabzug geschrieben) llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $b.bc
tkoenig1 commented 1 year ago

sv.txt If you have trouble reproducing the reduced test case above, here is the full one.

bagel99 commented 1 year ago

I was able to reproduce with your code snippet, although I got a different ICE: an assert. Weird code with the assignment float x = 0 + 0 * (float)i; One would think that this would have been optimized to float x = 0.0f; But anyway, fix coming soon.

bagel99 commented 1 year ago

Should be fixed by commit f2b14770a760dcf15fc4a1cb6cbe6771bc03a0ad.

tkoenig1 commented 1 year ago

It wasn't fixed in the original sources with my setup.

However, there is also something very fishy going on since a recent update, in which you appear to have updated LLVM to version 15 (did you?) In order to get reproducibility with your setup, I cleaned up my ~/bin and ~/lib directories, deleting cvise in the process. Now, cvise no longer builds, possibly because of some mixup between different LLVM and clang versions (?) so I cannot reduce the test cases any more.

And I have no idea how to fix it.

bagel99 commented 1 year ago

Its really the tail end of release 14, but the version numbers are bumped to 15.0.0, e.g. pre-release 15. All I build is opt, llc, clang. Maybe I'll soon start building flang.

tkoenig1 commented 1 year ago

I reinstalled the whole system on another machine, this time with cvise compiled before. Now it works again.

I still see the bug for

$ cat sv.i
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
S_utf8_mg_pos_cache_update() {
  float keep_earlier = 0 + 0 * (float)mg_ptr_3;
  if (keep_earlier)
    S_utf8_mg_pos_cache_update_cache_3 = 0;
}
$ 66 sv.i
sv.i:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
^
sv.i:1:11: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
          ^
sv.i:2:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
S_utf8_mg_pos_cache_update() {
^
sv.i:6:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
4 warnings generated.
LLVM ERROR: Cannot select: 0x55f420e6dba0: f32 = fma 0x55f420e6dad0, 0x55f420e6dc08, 0x55f420e6dc08
  0x55f420e6dad0: f32 = sint_to_fp 0x55f420e6dcd8
    0x55f420e6dcd8: i64,ch = load<(dereferenceable load (s32) from @mg_ptr_3, !tbaa !2), sext from i32> 0x55f420e25598, 0x55f420e6dfb0, undef:i64
      0x55f420e6dfb0: i64 = My66000ISD::WRAPPER TargetGlobalAddress:i64<i32* @mg_ptr_3> 0
        0x55f420e6db38: i64 = TargetGlobalAddress<i32* @mg_ptr_3> 0
      0x55f420e6da00: i64 = undef
  0x55f420e6dc08: f32 = My66000ISD::F32I5 Constant:i64<0>
    0x55f420e6d998: i64 = Constant<0>
  0x55f420e6dc08: f32 = My66000ISD::F32I5 Constant:i64<0>
    0x55f420e6d998: i64 = Constant<0>
In function: S_utf8_mg_pos_cache_update
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 sv_opt.bc
1.      Running pass 'Function Pass Manager' on module 'sv_opt.bc'.
2.      Running pass 'My66000 DAG->DAG Pattern Instruction Selection' on function '@S_utf8_mg_pos_cache_update'
 #0 0x000055f41d61665f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/asdf/bin/llc+0x2ee365f)
 #1 0x000055f41d61404e SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f1d69906420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #3 0x00007f1d693a300b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #4 0x00007f1d69382859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
 #5 0x000055f41d557347 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/asdf/bin/llc+0x2e24347)
 #6 0x000055f41d3fa5a0 llvm::SelectionDAGISel::CannotYetSelect(llvm::SDNode*) (/home/asdf/bin/llc+0x2cc75a0)
 #7 0x000055f41d3ffe22 llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/home/asdf/bin/llc+0x2ccce22)
 #8 0x000055f41c2744d7 (anonymous namespace)::My66000DAGToDAGISel::Select(llvm::SDNode*) My66000ISelDAGToDAG.cpp:0:0
 #9 0x000055f41d3f93b0 llvm::SelectionDAGISel::DoInstructionSelection() (/home/asdf/bin/llc+0x2cc63b0)
#10 0x000055f41d404409 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/home/asdf/bin/llc+0x2cd1409)
#11 0x000055f41d407061 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/asdf/bin/llc+0x2cd4061)
#12 0x000055f41d409be6 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.0) SelectionDAGISel.cpp:0:0
#13 0x000055f41c95fcfc llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/asdf/bin/llc+0x222ccfc)
#14 0x000055f41cdcdb90 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/asdf/bin/llc+0x269ab90)
#15 0x000055f41cdcdd09 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/asdf/bin/llc+0x269ad09)
#16 0x000055f41cdcf900 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/asdf/bin/llc+0x269c900)
#17 0x000055f41b092aeb compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#18 0x000055f41afad782 main (/home/asdf/bin/llc+0x87a782)
#19 0x00007f1d69384083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#20 0x000055f41b08af7e _start (/home/asdf/bin/llc+0x957f7e)
/home/asdf/bin/66: line 6: 230553 Aborted                 (core dumped) llc --disable-lsr --enable-predication --enable-predication2 --enable-carry-generation --early-carry-coalesce --enable-vvm -march=my66000 $b.bc

with clang version 15.0.0 (https://github.com/bagel99/llvm-my66000.git f2b14770a760dcf15fc4a1cb6cbe6771bc03a0ad)

bagel99 commented 1 year ago

I am mystified. The code snippet generates the code below. Even the sv.txt code compiles. S_utf8_mg_pos_cache_update: ; %bb.0: ldsw r1,[ip,mg_ptr_3] cvtsf r1,r1 cvtsf r2,#0 fmacf r1,r1,r2,r2 pfeqf r1,0,F stw #0,[ip,S_utf8_mg_pos_cache_update_cache_3] mov r1,#0 ret

tkoenig1 commented 1 year ago

I am mystified as well. There is a difference between our builds, but I cannot see what I am (presumably) doing wrong. In this case, I re-compiled llvm from source with the most recent version on a clean account on my home box. Here is a smal terminal session:

$ clang -fverbose-asm -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops sv.i
sv.i:1:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
^
sv.i:1:11: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
mg_ptr_3, S_utf8_mg_pos_cache_update_cache_3;
          ^
sv.i:2:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
S_utf8_mg_pos_cache_update() {
^
sv.i:6:1: warning: non-void function does not return a value [-Wreturn-type]
}
^
4 warnings generated.
$ llvm-dis sv.bc
$ cat sv.ll
; ModuleID = 'sv.bc'
source_filename = "sv.i"
target datalayout = "e-m:e-p:64:64-i1:8-i8:8-i16:16-i32:32-i64:64-f64:64-a:0:64-n64"
target triple = "my66000"

@mg_ptr_3 = dso_local local_unnamed_addr global i32 0, align 4
@S_utf8_mg_pos_cache_update_cache_3 = dso_local local_unnamed_addr global i32 0, align 4

; Function Attrs: mustprogress nofree nosync nounwind willreturn
define dso_local signext i32 @S_utf8_mg_pos_cache_update() local_unnamed_addr #0 {
  %1 = load i32, i32* @mg_ptr_3, align 4, !tbaa !2
  %2 = sitofp i32 %1 to float
  %3 = tail call float @llvm.fmuladd.f32(float %2, float 0.000000e+00, float 0.000000e+00)
  %4 = fcmp une float %3, 0.000000e+00
  br i1 %4, label %5, label %6

5:                                                ; preds = %0
  store i32 0, i32* @S_utf8_mg_pos_cache_update_cache_3, align 4, !tbaa !2
  br label %6

6:                                                ; preds = %5, %0
  ret i32 undef
}

; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare float @llvm.fmuladd.f32(float, float, float) #1

attributes #0 = { mustprogress nofree nosync nounwind willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 15.0.0 (https://github.com/bagel99/llvm-my66000.git f2b14770a760dcf15fc4a1cb6cbe6771bc03a0ad)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"int", !4, i64 0}
!4 = !{!"omnipotent char", !5, i64 0}
!5 = !{!"Simple C/C++ TBAA"}
$ llc sv.bc
LLVM ERROR: Cannot select: 0x55c609f79740: f32 = fma 0x55c609f79670, 0x55c609f797a8, 0x55c609f797a8
  0x55c609f79670: f32 = sint_to_fp 0x55c609f79878
    0x55c609f79878: i64,ch = load<(dereferenceable load (s32) from @mg_ptr_3, !tbaa !2), sext from i32> 0x55c609f2a338, 0x55c609f79b50, undef:i64
      0x55c609f79b50: i64 = My66000ISD::WRAPPER TargetGlobalAddress:i64<i32* @mg_ptr_3> 0
        0x55c609f796d8: i64 = TargetGlobalAddress<i32* @mg_ptr_3> 0
      0x55c609f795a0: i64 = undef
  0x55c609f797a8: f32 = My66000ISD::F32I5 Constant:i64<0>
    0x55c609f79538: i64 = Constant<0>
  0x55c609f797a8: f32 = My66000ISD::F32I5 Constant:i64<0>
    0x55c609f79538: i64 = Constant<0>
In function: S_utf8_mg_pos_cache_update
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: llc sv.bc
1.      Running pass 'Function Pass Manager' on module 'sv.bc'.
2.      Running pass 'My66000 DAG->DAG Pattern Instruction Selection' on function '@S_utf8_mg_pos_cache_update'
 #0 0x000055c605ced65f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/asdf/bin/llc+0x2ee365f)
 #1 0x000055c605ceb04e SignalHandler(int) Signals.cpp:0:0
 #2 0x00007fb039ae8420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #3 0x00007fb03958500b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #4 0x00007fb039564859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
 #5 0x000055c605c2e347 llvm::report_fatal_error(llvm::Twine const&, bool) (/home/asdf/bin/llc+0x2e24347)
 #6 0x000055c605ad15a0 llvm::SelectionDAGISel::CannotYetSelect(llvm::SDNode*) (/home/asdf/bin/llc+0x2cc75a0)
 #7 0x000055c605ad6e22 llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/home/asdf/bin/llc+0x2ccce22)
 #8 0x000055c60494b4d7 (anonymous namespace)::My66000DAGToDAGISel::Select(llvm::SDNode*) My66000ISelDAGToDAG.cpp:0:0
 #9 0x000055c605ad03b0 llvm::SelectionDAGISel::DoInstructionSelection() (/home/asdf/bin/llc+0x2cc63b0)
#10 0x000055c605adb409 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/home/asdf/bin/llc+0x2cd1409)
#11 0x000055c605ade061 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/home/asdf/bin/llc+0x2cd4061)
#12 0x000055c605ae0be6 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.0) SelectionDAGISel.cpp:0:0
#13 0x000055c605036cfc llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/home/asdf/bin/llc+0x222ccfc)
#14 0x000055c6054a4b90 llvm::FPPassManager::runOnFunction(llvm::Function&) (/home/asdf/bin/llc+0x269ab90)
#15 0x000055c6054a4d09 llvm::FPPassManager::runOnModule(llvm::Module&) (/home/asdf/bin/llc+0x269ad09)
#16 0x000055c6054a6900 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/home/asdf/bin/llc+0x269c900)
#17 0x000055c603769aeb compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#18 0x000055c603684782 main (/home/asdf/bin/llc+0x87a782)
#19 0x00007fb039566083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#20 0x000055c603761f7e _start (/home/asdf/bin/llc+0x957f7e)
Aborted (core dumped)
$ llc --version
LLVM (http://llvm.org/):
  LLVM version 15.0.0git
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver1

and the last change to the compiler I have is

$ git diff HEAD^1
diff --git a/llvm/lib/Target/My66000/My66000ISelLowering.cpp b/llvm/lib/Target/My66000/My66000ISelLowering.cpp
index 815789052c9c..9a19e4e435de 100644
--- a/llvm/lib/Target/My66000/My66000ISelLowering.cpp
+++ b/llvm/lib/Target/My66000/My66000ISelLowering.cpp
@@ -1233,7 +1233,7 @@ LLVM_DEBUG(dbgs() << "\tAttempt shrink to i5: " << isExact <<
       if (isExact) {
        int64_t imm = IVal.getExtValue();
         if (imm >= -16 && imm <= 15) {
-         return DAG.getNode(My66000ISD::F32I5, DL, MVT::f64,
+         return DAG.getNode(My66000ISD::F32I5, DL, MVT::f32,
                             DAG.getConstant(imm, DL, MVT::i64));
        }
       }

so the version is correct.

Could you maybe see what happens if you compile the *.ll file? I have also attached the files.

sv.zip

(and do you get the identical .bc and .ll files from the source?)

bagel99 commented 1 year ago

A clue, your .bc is different from mine. Yours has %2 = sitofp i32 %1 to float %3 = tail call float @llvm.fmuladd.f32(float %2, float 0.000000e+00, float 0.000000e+00) %4 = fcmp une float %3, 0.000000e+00 while mine has %2 = sitofp i32 %1 to float %3 = fmul float %2, 0.000000e+00llvm.fmuladd %4 = fadd float %3, 0.000000e+00 %5 = fcmp une float %4, 0.000000e+00 I don't know whether its the output of clang that's different or something opt does. We must be using different flags for them. Your .bc does trip the ICE. Anyway I currently don't have patterns to match "fma", which is what llvm.fmuladd turns into. I only have patterns for "fmad", which is what the DAG combiner generates from fadd(fmul ...). This obviously needs to be fixed.

tkoenig1 commented 1 year ago

I don't know whether its the output of clang that's different or something opt does. We must be using different flags for them.

I this case, it must be clang, sv.bc did not run through opt.

The first command of my compilation script is

clang -fverbose-asm -c --target=my66000 -O3 -fno-vectorize -fno-slp-vectorize  -emit-llvm -fno-unroll-loops $1

Anyway, in the future, I will also include the *.bc files in any future bug reports.

tkoenig1 commented 1 year ago

With the most recent compiler version, the errors in Perl are gone.

tkoenig1 commented 1 year ago

So, I think this can be closed as fixed.