LLVMのPoisonValueについて

2か月前にとりあえず書いたのに放置してしまってました!
ごめんなさいいいいいいいいいいいいいいい

C83で頒布した”きつねさんとおぼえるLLVM”に関して
hayamiz さんから下記のコメントを頂いておりました。

・Signed/Unsigned のオーバーフローって何?

このコメントを頂いた対象の文は

add 命令やsub 命令に現れるnsw やnuw は,No Unsigned Wrap とNo Signed Wrap の略で
それぞれUnsigned とSigned でオーバーフローが
発生した時にUndef Value(未定義の値) になるというフラグを意味します.

というものでした。

で、この質問の意図としては下記の二つがあるのかな、と感じたので
それぞれについて本エントリで修正と回答を書きたいと思います。

・Signed/Unsigned のオーバーフローって日本語としてわかりにくい
・Signed/Unsigned (の演算)でオーバーフローがおこるってどういうこと?

本文の表現について

まず、nswやnuwはオーバーフローが発生した時にPoison Valueになるというフラグなので
「add 命令やsub 命令に現れるnuw やnsw は,No Unsigned Wrap とNo Signed Wrap の略で
 それぞれUnsigned とSigned でオーバーフローが発生した時にPoison Value
 になるというフラグを意味します.」
というのが正しい文になります。申し訳ありませんでした。

で、”Unsigned とSigned でオーバーフローが発生”というのは
”Signed(符号付き),もしくはUnsigned (符号なし)の整数演算でオーバーフローが発生”
ということを意図していました。
ひょっとすると日本語の表現として分かり難くなっていたのかもしれません。
申し訳ありませんでした。

Signed/Unsignedのオーバーフローについて

一般的にUnsigned(符号なし)整数はオーバーフローしないことになっていますが,
これは演算結果がUnsigned の表現できる範囲を超えた場合,最大値+1を法とする剰余で表現する
というのが“決められている”からです.
整数演算の結果がオーバーフローする/しない,というのはアーキテクチャや処理系に依存するところで,
割と好きにしちゃえばいいところ(だと思う)

LLVMの話をすると,LLVM の整数演算命令,例えばadd 命令は
オペランドとしてinteger(整数型),もしくはintegerのvectorをとりますが,
そもそもLLVM のinteger(整数型)はi1,i8,i32 のようにビット幅を表現するのみでSigned/Unsigned は区別しない。
たぶんadd命令はあたられたオペランドの値を足すだけで
オペランドがSignedかUnsignedかなんて意識してないと思う.

Undef ValueとPoison Value の違い

今回Undef ValueとPoison Valueを間違えて記載してしまっていたのですが,
そもそも両者の違いは何なの?というのがあると思います.
これに関しては,かなりざっくり言うとUndef Valueは値でPoison Valueはフラグという認識です.

LLVMのLanguage Reference Manualによると
「Poison ValueはUndef Valueと似たようなものだけど
 副作用起こしてはいけない命令で未定義の動作がおこったことを表せるよ」
という感じのことが書いてあって,コード例とともに挙動が記載されています。

Poison Valueは例えばFFFFFF + 0000001みたいなaddがあった時は,
0が返るけど値はPoison Valueになっているというフラグがどこかにセットされる?
で,一度値がPoison Valueになるとその値を利用している演算には
Poison Valueであるというフラグが伝播していく,という感じに見えます.

Undef Valueについては,LLVMValueのサブクラスを見ているとUndefValueというのがあるので,
UndefValueを生成して値として使用できるのだと思う.(実際にUndefValueを使ったことはないです)

NSWとかNUWって何に使用するの?

最後に。。。
NSWとかNUWがPoisonValueに関連してるらしいけど
じゃあNSWとかNUWとかのフラグって何に使ってるの?という話.
正直そこまでは私もよくわかっていないです。
実装を追っていけば何をやっているかが見えるかと思うのですが,まだ見きれていないです。。。
フロントエンドは粛々と言語仕様に基づいて命令作るだけでいいかなーという感じ。