2015年07月

2015年07月23日

過去に何回か似たような記事を書いてますが、それのアップデートです。

内容的には、以下とほとんど同じ内容です。このツールの組み合わせでビルドが成功したというメモです。

LLVM 3.5(git リポジトリ)をMS VC++でビルド (2014/3/6)

(2015/9/4 追記: 下記手順で Express 2015 for Windows Desktop と LLVM 3.7.0 でもビルドと動作を確認しました。リンク先、中央の Community 2015 ではなく、下の方の Express for Windows Desktop からダウンロードしてください。)

続きを読む

2015年07月15日

不具合原因の詳細や、根本的な対策まではわかっていませんが、とりあえず現象と回避策を整理がてら記しておきます。

- 現象

Ubuntu 14.04/15.04 64bit (x86_64)上で Windows で動作する sh-*-elf ターゲットのクロス gcc を、Ubuntu の MinGW ツールチェーンでカナディアンクロスビルドすると、その gcc で特定パターンをコンパイルした時に、コンパイラ内部エラー(ICE)が発生する不具合がある。

gcc 4.8.4/4.8.5/4.9.2/4.9.3 で確認。32bit (x86) exe でも 64bit (x64) exe でも同じ結果。4.9.x が特に起こりやすく、libgcc の fp-bit.c コンパイル時に ICE が発生する。(後述するが、再現コードも作成できた。)4.8.x でも locale-inst.cc に -O2 以上の最適化で発生する。これらは Linux 上でネイティブ動作する sh のクロス gcc では発生しない。ソースや依存ライブラリ、configure 時のオプション等は、host の設定以外は全て Windows 向けと同じ。(また、Ubuntu 14.04 と 15.04 ではネイティブ、MinGW 共に gcc のバージョンが異なるが、あまり関係無いようだ。)

- 現状の回避策

32bit の Ubuntu (i386)上でカナディアンクロスビルドする。

- 原因の予想

おそらく gcc のカナディアンクロスビルドシステムにバグがある。特に、64bit Linux のネイティブ gcc は long が 64bit なのだが、MinGW gcc は 32bit でも 64bit でも long が 32bit (LLP64 モデル)なので、(gcc が LP64 モデルの Linux 上で使われてきた歴史を考えても)そのようなマイナーなパターンの対策は不十分な可能性が高い。また、sh のバックエンドの sh.md ファイルの記述のしかたにも問題があると思われる。具体的には、Tbit 操作のために 0x80000000 という定数が必要なようなのだが、md ファイル内では 10 進符号付整数しか記述できないようで、(const_int -2147483648) という、32bit の INT_MAX(2147483647)を超える即値が記述されている ※1。さらにややこしいことに、md ファイルは、genrecog という gcc の内部ツールにより、insn-recog.c に変換されてビルドされるのだが、この genrecog はビルド途中でネイティブ gcc でビルドされて作られ、一方 insn-recog.c は MinGW gcc でビルドされるのだが、その際の long の長さの違いが考慮されていない可能性が高い。

※1 C コンパイラは、通常はトークン単位で処理を行うため、仮に - が付いていても、- と 2147483648 は独立して処理されるので、問題が起こることがある。そのため INT_MIN は、通常は (-INT_MAX-1) のように定義されることが多く、MinGW gcc の limits.h もそうなっている。

詳細は以下になります。
続きを読む

記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード