コグノスケ


link 未来から過去へ表示  link 過去から未来へ表示(*)

link もっと前
2020年7月20日 >>> 2020年7月20日
link もっと後

2020年7月20日

GCCを調べる - その18 - ベクトルNot演算の定義

目次: GCC

前回(2020年7月19日の日記参照)は四則演算と論理演算(and, or, xor)を定義しました。今回はNot演算を定義します。他の論理演算と異なり、Not演算は2オペランドしか取りませんから、define_insnを別に書く必要があります。

ベクトルNot演算の定義

;; gcc/config/riscv/riscv.md

(define_insn "one_cmpl<mode>2"
  [(set (match_operand:ANYV           0 "register_operand" "=v")
	(not:ANYV (match_operand:ANYV 1 "register_operand" "%v")))]
  "TARGET_VECTOR"
  "vnot.vt%0,%1"
  [(set_attr "type" "logical")
   (set_attr "vecmode" "<MODE>")])

前回同様に、ベクトル拡張記法(Vector Extensions (Using the GNU Compiler Collection (GCC)))を使ってビット毎Notを使うプログラムを書きます。

ベクトルNot演算のサンプルプログラム

typedef int __v64si __attribute__((__vector_size__(256)));

void test()
{
	__v64si v10, v11;
	static int b[1024 * 1024] = {0};

	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v10) : "A"(b[10]));
	__asm__ volatile ("vlw.v %0, %1\n" : "=&v"(v11) : "A"(b[20]));

	v10 = ~v11;

	__asm__ volatile ("vsw.v %1, %0\n" : "=A"(b[40]) : "v"(v10));
}

コンパイルするとエラーが発生します。何かお気に召さないようです。

コンパイルエラー
$ riscv32-unknown-elf-gcc b.c -nostdlib -Og -march=rv32gcv -mabi=ilp32f

during RTL pass: reload
dump file: b.c.282r.reload
b.c: In function 'test':
b.c:14:1: internal compiler error: in setup_operand_alternative, at lra.c:814
   14 | }
      | ^
0xea5c36 setup_operand_alternative
        gcc/gcc/lra.c:814
0xea70c2 lra_set_insn_recog_data(rtx_insn*)
        gcc/gcc/lra.c:1073
0xea30f9 lra_get_insn_recog_data
        gcc/gcc/lra-int.h:488
0xeab0b9 remove_scratches_1
        gcc/gcc/lra.c:2058
0xeab4c4 remove_scratches
        gcc/gcc/lra.c:2094
0xeac629 lra(_IO_FILE*)
        gcc/gcc/lra.c:2396
0xe1a41f do_reload
        gcc/gcc/ira.c:5523
0xe1ae5c execute
        gcc/gcc/ira.c:5709

コードを見ると最後のオペランドに % を付けるべきではないそうです。確かにdefine_insnを見ると % が要らないのに付いています。

エラーを出している箇所

// gcc/lra.c

/* Setup info about operands in alternatives of LRA DATA of insn.  */
static void
setup_operand_alternative (lra_insn_recog_data_t data,
			   const operand_alternative *op_alt)
{
  int i, j, nop, nalt;
  int icode = data->icode;
  struct lra_static_insn_data *static_data = data->insn_static_data;

  static_data->commutative = -1;
  nop = static_data->n_operands;
  nalt = static_data->n_alternatives;
  static_data->operand_alternative = op_alt;
  for (i = 0; i < nop; i++)
    {
      static_data->operand[i].early_clobber_alts = 0;
      static_data->operand[i].is_address = false;
      if (static_data->operand[i].constraint[0] == '%')    //★★% が付いていればcommutative
	{
	  /* We currently only support one commutative pair of operands.  */
	  if (static_data->commutative < 0)
	    static_data->commutative = i;
	  else
	    lra_assert (icode < 0); /* Asm  */
	  /* The last operand should not be marked commutative.  */
	  lra_assert (i != nop - 1);    //★★このアサートに引っかかる
	}
    }

...

素直に応じるとエラーは消えます。

ベクトル演算のNotの定義(修正後)

(define_insn "one_cmpl<mode>2"
  [(set (match_operand:ANYV           0 "register_operand" "=v")
	(not:ANYV (match_operand:ANYV 1 "register_operand" " v")))]    ★★% を消す
  "TARGET_VECTOR"
  "vnot.vt%0,%1"
  [(set_attr "type" "logical")
   (set_attr "vecmode" "<MODE>")])

四則演算、論理演算(3オペランド系)と、Not演算(2オペランド系)が揃いました。残りの頻出する演算はビットシフト系かな?

最後のオペランドをcommutativeにできない理由

最後のオペランドをcommutativeにしてはいけない理由は、GCCのConstraintsの説明を見るとわかります。

`%' Declares the instruction to be commutative for this operand and the following operand. This means that the compiler may interchange the two operands if that is the cheapest way to make all operands fit the constraints. GCC can only handle one commutative pair in an asm; if you use more, the compiler may fail. Note that you need not use the modifier if the two alternatives are strictly identical; this would only waste time in the reload pass. The modifier is not operational after register allocation, so the result of define_peephole2 and define_splits performed after reload cannot rely on `%' to make the intended insn match.

難しいことを言っていますが、commutativeは % を付けたオペランドと「次」のオペランドが可換だと宣言することだそうです。最後のオペランドには「次」のオペランドがありませんから、% を付けてはいけません。なるほど。

RISC-Vの場合は論理演算のdefine_insnの2番目のオペランドに % が使われています。

RISC-Vスカラ論理演算の定義

;; gcc/config/riscv/riscv.md

;; This code iterator allows the three bitwise instructions to be generated
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])

...

(define_insn "<optab><mode>3"
  [(set (match_operand:X                0 "register_operand" "=r,r")
	(any_bitwise:X (match_operand:X 1 "register_operand" "%r,r")
		       (match_operand:X 2 "arith_operand"    " r,I")))]
  ""
  "<insn>%i2t%0,%1,%2"
  [(set_attr "type" "logical")
   (set_attr "mode" "<MODE>")])

例えばand r1, r2, r3とand r1, r3, r2は結果が同じですから、2番目と3番目のオペランドは入れ替え可能です。3つの論理演算(any_bitwiseはand, or, xorのこと)はいずれも同様に入れ替え可能ですので、このような定義になっています。

編集者:すずき(2023/09/24 11:52)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2020年7月20日 >>> 2020年7月20日
link もっと後

管理用メニュー

link 記事を新規作成

<2020>
<<<07>>>
---1234
567891011
12131415161718
19202122232425
262728293031-

最近のコメント5件

  • link 24年4月22日
    hdkさん (04/24 08:36)
    「うちのHHFZ4310は15年突破しまし...」
  • link 24年4月22日
    すずきさん (04/24 00:37)
    「ちゃんと数えてないですけど蛍光管が10年...」
  • link 24年4月22日
    hdkさん (04/23 20:52)
    「おお... うちのHHFZ4310より後...」
  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」

最近の記事3件

  • link 24年4月25日
    すずき (04/26 16:49)
    「[AVIFの変換] AVIFが読めないアプリケーションがたまにあるので、AVIF(AV1 Image File Format)...」
  • link 24年2月7日
    すずき (04/24 02:52)
    「[複数の音声ファイルのラウドネスを統一したい] PCやデジタル音楽プレーヤーで音楽を聞いていると、曲によって音量の大小が激しく...」
  • link 24年4月22日
    すずき (04/23 20:13)
    「[仕事部屋の照明が壊れた] いきなり仕事部屋のシーリングライトが消えました。蛍光管の寿命にしては去年(2022年10月19日の...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/26 16:49