mirror of https://github.com/llvm/circt.git
1771 lines
68 KiB
MLIR
1771 lines
68 KiB
MLIR
// RUN: circt-opt -canonicalize='top-down=true region-simplify=aggressive' %s | FileCheck %s
|
|
|
|
// CHECK-LABEL: hw.module @extract_noop(in %arg0 : i3, out "" : i3) {
|
|
// CHECK-NEXT: hw.output %arg0
|
|
|
|
hw.module @extract_noop(in %arg0 : i3, out "": i3) {
|
|
%x = comb.extract %arg0 from 0 : (i3) -> i3
|
|
hw.output %x : i3
|
|
}
|
|
|
|
// Constant Folding
|
|
|
|
// CHECK-LABEL: hw.module @extract_cstfold(out result : i3) {
|
|
// CHECK-NEXT: %c-3_i3 = hw.constant -3 : i3
|
|
// CHECK-NEXT: hw.output %c-3_i3
|
|
|
|
hw.module @extract_cstfold(out result : i3) {
|
|
%c42_i12 = hw.constant 42 : i12
|
|
%x = comb.extract %c42_i12 from 3 : (i12) -> i3
|
|
hw.output %x : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @and_cstfold(in %arg0 : i7, out result : i7) {
|
|
// CHECK-NEXT: %c1_i7 = hw.constant 1 : i7
|
|
// CHECK-NEXT: %0 = comb.and %arg0, %c1_i7 : i7
|
|
// CHECK-NEXT: hw.output %0 : i7
|
|
|
|
hw.module @and_cstfold(in %arg0 : i7, out result : i7) {
|
|
%c11_i7 = hw.constant 11 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%0 = comb.and %arg0, %c11_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_cstfold(in %arg0 : i7, out result : i7) {
|
|
// CHECK-NEXT: %c15_i7 = hw.constant 15 : i7
|
|
// CHECK-NEXT: %0 = comb.or %arg0, %c15_i7 : i7
|
|
// CHECK-NEXT: hw.output %0 : i7
|
|
|
|
hw.module @or_cstfold(in %arg0 : i7, out result : i7) {
|
|
%c11_i7 = hw.constant 11 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%0 = comb.or %arg0, %c11_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_cstfold(in %arg0 : i7, out result : i7) {
|
|
// CHECK-NEXT: %c14_i7 = hw.constant 14 : i7
|
|
// CHECK-NEXT: %0 = comb.xor %arg0, %c14_i7 : i7
|
|
// CHECK-NEXT: hw.output %0 : i7
|
|
|
|
hw.module @xor_cstfold(in %arg0 : i7, out result : i7) {
|
|
%c11_i7 = hw.constant 11 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%0 = comb.xor %arg0, %c11_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_cstfold(in %arg0 : i7, out result : i7) {
|
|
// CHECK-NEXT: %c15_i7 = hw.constant 15 : i7
|
|
// CHECK-NEXT: %0 = comb.add %arg0, %c15_i7 : i7
|
|
// CHECK-NEXT: hw.output %0 : i7
|
|
hw.module @add_cstfold(in %arg0 : i7, out result : i7) {
|
|
%c10_i7 = hw.constant 10 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%0 = comb.add %arg0, %c10_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_cstfold(in %arg0 : i7, out result : i7) {
|
|
// CHECK-NEXT: %c15_i7 = hw.constant 15 : i7
|
|
// CHECK-NEXT: %0 = comb.mul %arg0, %c15_i7 : i7
|
|
// CHECK-NEXT: hw.output %0 : i7
|
|
hw.module @mul_cstfold(in %arg0 : i7, out result : i7) {
|
|
%c3_i7 = hw.constant 3 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%0 = comb.mul %arg0, %c3_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @div_cstfold(in %arg0 : i7, out result : i7, out a : i7, out b : i7, out c : i7) {
|
|
// CHECK-NEXT: %c2_i7 = hw.constant 2 : i7
|
|
// CHECK-NEXT: %c-3_i7 = hw.constant -3 : i7
|
|
// CHECK-NEXT: hw.output %c2_i7, %arg0, %c-3_i7, %arg0 : i7, i7, i7, i7
|
|
hw.module @div_cstfold(in %arg0 : i7, out result : i7, out a: i7, out b: i7, out c: i7) {
|
|
%c1_i7 = hw.constant 1 : i7
|
|
%c-3_i7 = hw.constant -3 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%c10_i7 = hw.constant 10 : i7
|
|
%a = comb.divu %c10_i7, %c5_i7 : i7
|
|
%b = comb.divu %arg0, %c1_i7 : i7
|
|
|
|
%c = comb.divs %c10_i7, %c-3_i7 : i7
|
|
%d = comb.divs %arg0, %c1_i7 : i7
|
|
|
|
hw.output %a, %b, %c, %d : i7, i7, i7, i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mod_cstfold(in %arg0 : i7, out result : i7, out a : i7, out b : i7, out c : i7) {
|
|
// CHECK-NEXT: %c0_i7 = hw.constant 0 : i7
|
|
// CHECK-NEXT: %c1_i7 = hw.constant 1 : i7
|
|
// CHECK-NEXT: hw.output %c0_i7, %c0_i7, %c1_i7, %c0_i7 : i7, i7, i7, i7
|
|
hw.module @mod_cstfold(in %arg0 : i7, out result : i7, out a: i7, out b: i7, out c: i7) {
|
|
%c1_i7 = hw.constant 1 : i7
|
|
%c-3_i7 = hw.constant -3 : i7
|
|
%c5_i7 = hw.constant 5 : i7
|
|
%c10_i7 = hw.constant 10 : i7
|
|
%a = comb.modu %c10_i7, %c5_i7 : i7
|
|
%b = comb.modu %arg0, %c1_i7 : i7
|
|
|
|
%c = comb.mods %c10_i7, %c-3_i7 : i7
|
|
%d = comb.mods %arg0, %c1_i7 : i7
|
|
|
|
hw.output %a, %b, %c, %d : i7, i7, i7, i7
|
|
}
|
|
// CHECK-LABEL: hw.module @variadic_noop(in %arg0 : i11, out result : i11) {
|
|
// CHECK-NEXT: hw.output %arg0
|
|
|
|
hw.module @variadic_noop(in %arg0 : i11, out result : i11) {
|
|
%0 = comb.and %arg0 : i11
|
|
%1 = comb.or %0 : i11
|
|
%2 = comb.xor %1 : i11
|
|
%3 = comb.add %2 : i11
|
|
%4 = comb.mul %3 : i11
|
|
hw.output %4 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @and_annulment0(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c0_i11 = hw.constant 0 : i11
|
|
// CHECK-NEXT: hw.output %c0_i11
|
|
|
|
hw.module @and_annulment0(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.and %arg0, %arg1, %c0_i11 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @and_annulment1
|
|
// CHECK-NEXT: %c0_i7 = hw.constant 0 : i7
|
|
// CHECK-NEXT: hw.output %c0_i7
|
|
|
|
hw.module @and_annulment1(in %arg0 : i7, out result : i7) {
|
|
%c1_i7 = hw.constant 1 : i7
|
|
%c2_i7 = hw.constant 2 : i7
|
|
%c4_i7 = hw.constant 4 : i7
|
|
%0 = comb.and %arg0, %c1_i7, %c2_i7, %c4_i7: i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_annulment0(in %arg0 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c-1_i11 = hw.constant -1 : i11
|
|
// CHECK-NEXT: hw.output %c-1_i11
|
|
|
|
hw.module @or_annulment0(in %arg0 : i11, out result : i11) {
|
|
%c-1_i11 = hw.constant -1 : i11
|
|
%0 = comb.or %arg0, %arg0, %arg0, %c-1_i11 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_annulment1
|
|
// CHECK-NEXT: %c-1_i3 = hw.constant -1 : i3
|
|
// CHECK-NEXT: hw.output %c-1_i3
|
|
|
|
hw.module @or_annulment1(in %arg0 : i3, out result : i3) {
|
|
%c1_i3 = hw.constant 1 : i3
|
|
%c2_i3 = hw.constant 2 : i3
|
|
%c4_i3 = hw.constant 4 : i3
|
|
%0 = comb.or %arg0, %c1_i3, %c2_i3, %c4_i3: i3
|
|
hw.output %0 : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_annulment
|
|
// CHECK-NEXT: %c0_i11 = hw.constant 0 : i11
|
|
// CHECK-NEXT: hw.output %c0_i11
|
|
|
|
hw.module @mul_annulment(in %arg0 : i11, in %arg1 : i11, in %arg2 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.mul %arg0, %c0_i11, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_overflow
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: hw.output %c0_i2
|
|
|
|
hw.module @mul_overflow(in %arg0 : i2, out result : i2) {
|
|
%c2_i2 = hw.constant 2 : i2
|
|
%0 = comb.mul %arg0, %c2_i2, %c2_i2 : i2
|
|
hw.output %0 : i2
|
|
}
|
|
|
|
// Flattening
|
|
|
|
// CHECK-LABEL: hw.module @and_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.and %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @and_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%and0 = comb.and %arg1, %arg2 : i7
|
|
%0 = comb.and %arg0, %and0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @and_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.and %arg0, %arg1, %arg2, %arg3 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @and_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
%and0 = comb.and %arg1, %arg2 : i7
|
|
%0 = comb.and %arg0, %and0, %arg3 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @and_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.and %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @and_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%and0 = comb.and %arg0, %arg1 : i7
|
|
%0 = comb.and %and0, %arg2 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @or_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%or0 = comb.or %arg1, %arg2 : i7
|
|
%0 = comb.or %arg0, %or0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_flatten_keep_root_name(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1, %arg2 {sv.namehint = "waterman"} : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @or_flatten_keep_root_name(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%or0 = comb.or %arg1, %arg2 : i7
|
|
%0 = comb.or %arg0, %or0 {sv.namehint="waterman"}: i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1, %arg2, %arg3 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @or_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
%or0 = comb.or %arg1, %arg2 : i7
|
|
%0 = comb.or %arg0, %or0, %arg3 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @or_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%or0 = comb.or %arg0, %arg1 : i7
|
|
%0 = comb.or %or0, %arg2 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.xor %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @xor_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%xor0 = comb.xor %arg1, %arg2 : i7
|
|
%0 = comb.xor %arg0, %xor0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.xor %arg0, %arg1, %arg2, %arg3 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @xor_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
%xor0 = comb.xor %arg1, %arg2 : i7
|
|
%0 = comb.xor %arg0, %xor0, %arg3 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.xor %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @xor_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%xor0 = comb.xor %arg0, %arg1 : i7
|
|
%0 = comb.xor %xor0, %arg2 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
hw.module @add_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%add0 = comb.add %arg1, %arg2 : i7
|
|
%0 = comb.add %arg0, %add0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.add %arg0, %arg1, %arg2, %arg3 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @add_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
%add0 = comb.add %arg1, %arg2 : i7
|
|
%0 = comb.add %arg0, %add0, %arg3 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.add %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @add_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%add0 = comb.add %arg0, %arg1 : i7
|
|
%0 = comb.add %add0, %arg2 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
hw.module @mul_flatten_in_back(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%mul0 = comb.mul %arg1, %arg2 : i7
|
|
%0 = comb.mul %arg0, %mul0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.mul %arg0, %arg1, %arg2, %arg3 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @mul_flatten_in_middle(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, in %arg3 : i7, out result : i7) {
|
|
%mul0 = comb.mul %arg1, %arg2 : i7
|
|
%0 = comb.mul %arg0, %mul0, %arg3 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.mul %arg0, %arg1, %arg2 : i7
|
|
// CHECK-NEXT: hw.output [[RES]] : i7
|
|
|
|
hw.module @mul_flatten_in_front(in %arg0 : i7, in %arg1 : i7, in %arg2 : i7, out result : i7) {
|
|
%mul0 = comb.mul %arg0, %arg1 : i7
|
|
%0 = comb.mul %mul0, %arg2 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// Identities
|
|
|
|
// CHECK-LABEL: hw.module @and_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.and %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @and_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c-1_i11 = hw.constant -1 : i11
|
|
%0 = comb.and %c-1_i11, %arg0, %arg1, %c-1_i11 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @or_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.or %arg0, %c0_i11, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.xor %arg1, %arg0
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @xor_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.xor %c0_i11, %arg1, %arg0 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.add %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @add_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.add %arg0, %c0_i11, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mul_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.mul %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @mul_identity(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c1_i11 = hw.constant 1 : i11
|
|
%0 = comb.mul %arg0, %c1_i11, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// Idempotency
|
|
|
|
// CHECK-LABEL: hw.module @and_idempotent(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c9_i11 = hw.constant 9 : i11
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.and %arg0, %arg1, %c9_i11
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @and_idempotent(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c9_i11 = hw.constant 9 : i11
|
|
%0 = comb.and %arg0, %arg1, %c9_i11, %c9_i11 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @or_idempotent(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.or %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @or_idempotent(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%0 = comb.or %arg0, %arg1, %arg1, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_idempotent(in %arg0 : i11, in %arg1 : i11, in %arg2 : i11, out result : i11) {
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.xor %arg0, %arg1
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @xor_idempotent(in %arg0 : i11, in %arg1 : i11, in %arg2 : i11, out result : i11) {
|
|
%0 = comb.xor %arg0, %arg1, %arg2, %arg2 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @xor_idempotent_two_arguments(in %arg0 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c0_i11 = hw.constant 0 : i11
|
|
// CHECK-NEXT: hw.output %c0_i11 : i11
|
|
|
|
hw.module @xor_idempotent_two_arguments(in %arg0 : i11, out result : i11) {
|
|
%c0_i11 = hw.constant 0 : i11
|
|
%0 = comb.xor %arg0, %arg0 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// Add reduction to shift left and multiplication.
|
|
|
|
// CHECK-LABEL: hw.module @add_reduction1(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: [[EXTRACT:%[0-9]+]] = comb.extract %arg1 from 0 : (i11) -> i10
|
|
// CHECK-NEXT: [[CONCAT:%[0-9]+]] = comb.concat [[EXTRACT]], %false : i10, i1
|
|
// CHECK-NEXT: hw.output [[CONCAT]]
|
|
|
|
hw.module @add_reduction1(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%0 = comb.add %arg1, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_reduction2(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c3_i11 = hw.constant 3 : i11
|
|
// CHECK-NEXT: [[RES:%[0-9]+]] = comb.mul %arg1, %c3_i11
|
|
// CHECK-NEXT: hw.output [[RES]]
|
|
|
|
hw.module @add_reduction2(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%0 = comb.add %arg1, %arg1, %arg1 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @add_reduction3(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %c0_i3 = hw.constant 0 : i3
|
|
// CHECK-NEXT: [[EXTRACT:%[0-9]+]] = comb.extract %arg1 from 0 : (i11) -> i8
|
|
// CHECK-NEXT: [[CONCAT:%[0-9]+]] = comb.concat [[EXTRACT]], %c0_i3 : i8, i3
|
|
// CHECK-NEXT: hw.output [[CONCAT]]
|
|
|
|
hw.module @add_reduction3(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c7_i11 = hw.constant 7 : i11
|
|
%0 = comb.mul %arg1, %c7_i11 : i11
|
|
%1 = comb.add %arg1, %0 : i11
|
|
hw.output %1 : i11
|
|
}
|
|
|
|
// Multiply reduction to shift left.
|
|
|
|
// CHECK-LABEL: hw.module @multiply_reduction(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: [[EXTRACT:%[0-9]+]] = comb.extract %arg1 from 0 : (i11) -> i10
|
|
// CHECK-NEXT: [[CONCAT:%[0-9]+]] = comb.concat [[EXTRACT]], %false : i10, i1
|
|
// CHECK-NEXT: hw.output [[CONCAT]]
|
|
|
|
hw.module @multiply_reduction(in %arg0 : i11, in %arg1 : i11, out result : i11) {
|
|
%c2_i11 = hw.constant 2 : i11
|
|
%0 = comb.mul %arg1, %c2_i11 : i11
|
|
hw.output %0 : i11
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @parity_constant_folding1(out result : i1) {
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: hw.output %true : i1
|
|
|
|
hw.module @parity_constant_folding1(out result : i1) {
|
|
%c4_i4 = hw.constant 4 : i4
|
|
%0 = comb.parity %c4_i4 : i4
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @parity_constant_folding2(out result : i1) {
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: hw.output %false : i1
|
|
hw.module @parity_constant_folding2(out result : i1) {
|
|
%c15_i4 = hw.constant 15 : i4
|
|
%0 = comb.parity %c15_i4 : i4
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold_0
|
|
// CHECK-NEXT: %c120_i8 = hw.constant 120 : i8
|
|
hw.module @concat_fold_0(out result : i8) {
|
|
%c7_i4 = hw.constant 7 : i4
|
|
%c4_i3 = hw.constant 4 : i3
|
|
%false = hw.constant false
|
|
%0 = comb.concat %c7_i4, %c4_i3, %false : i4, i3, i1
|
|
hw.output %0 : i8
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold_1
|
|
// CHECK-NEXT: %0 = comb.concat %arg0, %arg1, %arg2
|
|
hw.module @concat_fold_1(in %arg0 : i4, in %arg1 : i3, in %arg2 : i1, out result : i8) {
|
|
%a = comb.concat %arg0, %arg1 : i4, i3
|
|
%b = comb.concat %a, %arg2 : i7, i1
|
|
hw.output %b : i8
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold_3
|
|
// CHECK-NEXT: %c60_i7 = hw.constant 60 : i7
|
|
// CHECK-NEXT: %0 = comb.concat %c60_i7, %arg0 : i7, i1
|
|
hw.module @concat_fold_3(in %arg0 : i1, out result : i8) {
|
|
%c7_i4 = hw.constant 7 : i4
|
|
%c4_i3 = hw.constant 4 : i3
|
|
%0 = comb.concat %c7_i4, %c4_i3, %arg0 : i4, i3, i1
|
|
hw.output %0 : i8
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold_4
|
|
hw.module @concat_fold_4(in %arg0 : i3, out result : i5) {
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 2 : (i3) -> i1
|
|
%0 = comb.extract %arg0 from 2 : (i3) -> i1
|
|
// CHECK-NEXT: %1 = comb.replicate %0 : (i1) -> i2
|
|
%1 = comb.concat %0, %0, %arg0 : i1, i1, i3
|
|
// CHECK-NEXT: %2 = comb.concat %1, %arg0 : i2, i3
|
|
hw.output %1 : i5
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold_5
|
|
// CHECK-NEXT: %0 = comb.concat %arg0, %arg1 : i3, i3
|
|
// CHECK-NEXT: hw.output %0, %arg0
|
|
hw.module @concat_fold_5(in %arg0 : i3, in %arg1 : i3, out result : i6, out a: i3) {
|
|
%0 = comb.extract %arg0 from 2 : (i3) -> i1
|
|
%1 = comb.extract %arg0 from 0 : (i3) -> i2
|
|
%2 = comb.concat %0, %1, %arg1 : i1, i2, i3
|
|
|
|
%3 = comb.concat %0, %1 : i1, i2
|
|
hw.output %2, %3 : i6, i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold6(in %arg0 : i5, in %arg1 : i3, out result : i4) {
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 1 : (i5) -> i4
|
|
// CHECK-NEXT: hw.output %0 : i4
|
|
hw.module @concat_fold6(in %arg0 : i5, in %arg1 : i3, out result : i4) {
|
|
%0 = comb.extract %arg0 from 3 : (i5) -> i2
|
|
%1 = comb.extract %arg0 from 1 : (i5) -> i2
|
|
%2 = comb.concat %0, %1 : i2, i2
|
|
hw.output %2 : i4
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold7(in %arg0 : i5, out result : i20) {
|
|
// CHECK-NEXT: %0 = comb.replicate %arg0 : (i5) -> i20
|
|
// CHECK-NEXT: hw.output %0 : i20
|
|
hw.module @concat_fold7(in %arg0 : i5, out result : i20) {
|
|
%0 = comb.concat %arg0, %arg0, %arg0, %arg0 : i5, i5, i5, i5
|
|
hw.output %0 : i20
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @concat_fold8
|
|
hw.module @concat_fold8(in %arg0 : i5, in %arg1 : i3, out r0: i28, out r1: i28, out r2: i13) {
|
|
%0 = comb.replicate %arg0 : (i5) -> i20
|
|
|
|
// CHECK-NEXT: %0 = comb.replicate %arg0 : (i5) -> i25
|
|
// CHECK-NEXT: %1 = comb.concat %arg1, %0 : i3, i25
|
|
%1 = comb.concat %arg1, %arg0, %0 : i3, i5, i20
|
|
|
|
// CHECK-NEXT: %2 = comb.replicate %arg0 : (i5) -> i25
|
|
// CHECK-NEXT: %3 = comb.concat %arg1, %2 : i3, i25
|
|
%2 = comb.concat %arg1, %0, %arg0 : i3, i20, i5
|
|
|
|
// CHECK-NEXT: %4 = comb.replicate %arg0 : (i5) -> i10
|
|
// CHECK-NEXT: %5 = comb.concat %arg1, %4 : i3, i10
|
|
%3 = comb.concat %arg1, %arg0, %arg0 : i3, i5, i5
|
|
|
|
// CHECK-NEXT: hw.output %1, %3, %5
|
|
hw.output %1, %2, %3 : i28, i28, i13
|
|
}
|
|
|
|
|
|
// CHECK-LABEL: hw.module @mux_fold0
|
|
// CHECK-NEXT: hw.output %arg0 : i3
|
|
hw.module @mux_fold0(in %arg0 : i3, in %arg1 : i3, out result : i3) {
|
|
%c1_i1 = hw.constant 1 : i1
|
|
%0 = comb.mux %c1_i1, %arg0, %arg1 : i3
|
|
hw.output %0 : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mux_fold1
|
|
// CHECK-NEXT: hw.output %arg1 : i3
|
|
hw.module @mux_fold1(in %arg0 : i1, in %arg1 : i3, out result : i3) {
|
|
%0 = comb.mux %arg0, %arg1, %arg1 : i3
|
|
hw.output %0 : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_constants
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: hw.output %false : i1
|
|
hw.module @icmp_fold_constants(out result : i1) {
|
|
%c2_i2 = hw.constant 2 : i2
|
|
%c3_i2 = hw.constant 3 : i2
|
|
%0 = comb.icmp uge %c2_i2, %c3_i2 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_same_operands
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: hw.output %false : i1
|
|
hw.module @icmp_fold_same_operands(in %arg0 : i2, out result : i1) {
|
|
%0 = comb.icmp ugt %arg0, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_constant_rhs0(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: hw.output %false : i1
|
|
hw.module @icmp_fold_constant_rhs0(in %arg0 : i2, out result : i1) {
|
|
%c3_i2 = hw.constant 3 : i2
|
|
%0 = comb.icmp ugt %arg0, %c3_i2 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_constant_rhs1(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: hw.output %false : i1
|
|
hw.module @icmp_fold_constant_rhs1(in %arg0 : i2, out result : i1) {
|
|
%c-2_i2 = hw.constant -2 : i2
|
|
%0 = comb.icmp slt %arg0, %c-2_i2 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_constant_lhs0(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: hw.output %true : i1
|
|
hw.module @icmp_fold_constant_lhs0(in %arg0 : i2, out result : i1) {
|
|
%c3_i2 = hw.constant 3 : i2
|
|
%0 = comb.icmp uge %c3_i2, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_constant_lhs1(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: hw.output %true : i1
|
|
hw.module @icmp_fold_constant_lhs1(in %arg0 : i2, out result : i1) {
|
|
%c-2_i2 = hw.constant -2 : i2
|
|
%0 = comb.icmp sle %c-2_i2, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_canonicalize0(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %c-1_i2 = hw.constant -1 : i2
|
|
// CHECK-NEXT: %0 = comb.icmp sgt %arg0, %c-1_i2 : i2
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @icmp_canonicalize0(in %arg0 : i2, out result : i1) {
|
|
%c-1_i2 = hw.constant -1 : i2
|
|
%0 = comb.icmp slt %c-1_i2, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_canonicalize_ne(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %c-2_i2 = hw.constant -2 : i2
|
|
// CHECK-NEXT: %0 = comb.icmp ne %arg0, %c-2_i2 : i2
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @icmp_canonicalize_ne(in %arg0 : i2, out result : i1) {
|
|
%c-2_i2 = hw.constant -2 : i2
|
|
%0 = comb.icmp slt %c-2_i2, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_canonicalize_eq(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %c-2_i2 = hw.constant -2 : i2
|
|
// CHECK-NEXT: %0 = comb.icmp eq %arg0, %c-2_i2 : i2
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @icmp_canonicalize_eq(in %arg0 : i2, out result : i1) {
|
|
%c-1_i2 = hw.constant -1 : i2
|
|
%0 = comb.icmp slt %arg0, %c-1_i2: i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_canonicalize_sgt(in %arg0 : i2, out result : i1) {
|
|
// CHECK-NEXT: %c-1_i2 = hw.constant -1 : i2
|
|
// CHECK-NEXT: %0 = comb.icmp sgt %arg0, %c-1_i2 : i2
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @icmp_canonicalize_sgt(in %arg0 : i2, out result : i1) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%0 = comb.icmp sle %c0_i2, %arg0 : i2
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shl_fold1(out result : i12) {
|
|
// CHECK-NEXT: %c84_i12 = hw.constant 84 : i12
|
|
// CHECK-NEXT: hw.output %c84_i12 : i12
|
|
hw.module @shl_fold1(out result : i12) {
|
|
%c42_i12 = hw.constant 42 : i12
|
|
%c1_i12 = hw.constant 1 : i12
|
|
%0 = comb.shl %c42_i12, %c1_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shl_fold2(out result : i12) {
|
|
// CHECK-NEXT: %c0_i12 = hw.constant 0 : i12
|
|
// CHECK-NEXT: hw.output %c0_i12 : i12
|
|
hw.module @shl_fold2(out result : i12) {
|
|
%c1_i12 = hw.constant 1 : i12
|
|
%c10_i12 = hw.constant 12 : i12
|
|
%0 = comb.shl %c1_i12, %c10_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shl_fold3(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: %c0_i12 = hw.constant 0 : i12
|
|
// CHECK-NEXT: hw.output %c0_i12 : i12
|
|
hw.module @shl_fold3(in %arg0 : i12, out result : i12) {
|
|
%c12_i12 = hw.constant 12 : i12
|
|
%0 = comb.shl %arg0, %c12_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shl_fold4(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: hw.output %arg0 : i12
|
|
hw.module @shl_fold4(in %arg0 : i12, out result : i12) {
|
|
%c0_i12 = hw.constant 0 : i12
|
|
%0 = comb.shl %arg0, %c0_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shl_shift_to_extract_and_concat(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 0 : (i12) -> i10
|
|
// CHECK-NEXT: %1 = comb.concat %0, %c0_i2 : i10, i2
|
|
// CHECK-NEXT: hw.output %1
|
|
hw.module @shl_shift_to_extract_and_concat(in %arg0 : i12, out result : i12) {
|
|
%c2_i12 = hw.constant 2 : i12
|
|
%0 = comb.shl %arg0, %c2_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_fold1
|
|
// CHECK-NEXT: %c21_i12 = hw.constant 21 : i12
|
|
// CHECK-NEXT: hw.output %c21_i12 : i12
|
|
hw.module @shru_fold1(out result : i12) {
|
|
%c42_i12 = hw.constant 42 : i12
|
|
%c1_i12 = hw.constant 1 : i12
|
|
%0 = comb.shru %c42_i12, %c1_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_fold2
|
|
// CHECK-NEXT: %c2047_i12 = hw.constant 2047 : i12
|
|
// CHECK-NEXT: hw.output %c2047_i12 : i12
|
|
hw.module @shru_fold2(out result : i12) {
|
|
%c-1_i12 = hw.constant -1 : i12
|
|
%c1_i12 = hw.constant 1 : i12
|
|
%0 = comb.shru %c-1_i12, %c1_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_fold3
|
|
// CHECK-NEXT: %c0_i12 = hw.constant 0 : i12
|
|
// CHECK-NEXT: hw.output %c0_i12 : i12
|
|
hw.module @shru_fold3(in %arg0 : i12, out result : i12) {
|
|
%c12_i12 = hw.constant 12 : i12
|
|
%0 = comb.shru %arg0, %c12_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_fold4
|
|
// CHECK-NEXT: hw.output %arg0 : i12
|
|
hw.module @shru_fold4(in %arg0 : i12, out result : i12) {
|
|
%c0_i12 = hw.constant 0 : i12
|
|
%0 = comb.shru %arg0, %c0_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_shift_to_extract_and_concat(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 2 : (i12) -> i10
|
|
// CHECK-NEXT: %1 = comb.concat %c0_i2, %0 : i2, i10
|
|
// CHECK-NEXT: hw.output %1
|
|
hw.module @shru_shift_to_extract_and_concat(in %arg0 : i12, out result : i12) {
|
|
%c2_i12 = hw.constant 2 : i12
|
|
%0 = comb.shru %arg0, %c2_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shrs_fold1(out result : i12) {
|
|
// CHECK-NEXT: %c21_i12 = hw.constant 21 : i12
|
|
// CHECK-NEXT: hw.output %c21_i12 : i12
|
|
hw.module @shrs_fold1(out result : i12) {
|
|
%c42_i12 = hw.constant 42 : i12
|
|
%c1_i12 = hw.constant 1 : i12
|
|
%0 = comb.shrs %c42_i12, %c1_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shrs_fold2(out result : i12) {
|
|
// CHECK-NEXT: %c-3_i12 = hw.constant -3 : i12
|
|
// CHECK-NEXT: hw.output %c-3_i12 : i12
|
|
hw.module @shrs_fold2(out result : i12) {
|
|
%c-5_i12 = hw.constant -5 : i12
|
|
%c10_i12 = hw.constant 1 : i12
|
|
%0 = comb.shrs %c-5_i12, %c10_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shrs_fold3(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: hw.output %arg0 : i12
|
|
hw.module @shrs_fold3(in %arg0 : i12, out result : i12) {
|
|
%c0_i12 = hw.constant 0 : i12
|
|
%0 = comb.shrs %arg0, %c0_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_shift_to_extract_and_concat0(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 11 : (i12) -> i1
|
|
// CHECK-NEXT: %1 = comb.replicate %0 : (i1) -> i12
|
|
// CHECK-NEXT: hw.output %1 : i12
|
|
hw.module @shru_shift_to_extract_and_concat0(in %arg0 : i12, out result : i12) {
|
|
%c12_i12 = hw.constant 12 : i12
|
|
%0 = comb.shrs %arg0, %c12_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @shru_shift_to_extract_and_concat1(in %arg0 : i12, out result : i12) {
|
|
// CHECK-NEXT: %0 = comb.extract %arg0 from 11 : (i12) -> i1
|
|
// CHECK-NEXT: %1 = comb.replicate %0 : (i1) -> i2
|
|
// CHECK-NEXT: %2 = comb.extract %arg0 from 2 : (i12) -> i10
|
|
// CHECK-NEXT: %3 = comb.concat %1, %2 : i2, i10
|
|
// CHECK-NEXT: hw.output %3
|
|
hw.module @shru_shift_to_extract_and_concat1(in %arg0 : i12, out result : i12) {
|
|
%c2_i12 = hw.constant 2 : i12
|
|
%0 = comb.shrs %arg0, %c2_i12 : i12
|
|
hw.output %0 : i12
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mux_canonicalize0
|
|
// CHECK-NEXT: %0 = comb.or %a, %b : i1
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @mux_canonicalize0(in %a: i1, in %b: i1, out result : i1) {
|
|
%true = hw.constant true
|
|
%0 = comb.mux %a, %true, %b : i1
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mux_canonicalize1
|
|
// CHECK-NEXT: %0 = comb.and %a, %b : i1
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @mux_canonicalize1(in %a: i1, in %b: i1, out result : i1) {
|
|
%false = hw.constant false
|
|
%0 = comb.mux %a, %b, %false : i1
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mux_canonicalize2
|
|
// CHECK-NEXT: %0 = comb.or %a, %b : i1
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @mux_canonicalize2(in %a: i1, in %b: i1, out result : i1) {
|
|
%c-1_i1 = hw.constant -1 : i1
|
|
%0 = comb.mux %a, %c-1_i1, %b : i1
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @mux_canonicalize3
|
|
// CHECK-NEXT: %0 = comb.and %a, %b : i1
|
|
// CHECK-NEXT: hw.output %0 : i1
|
|
hw.module @mux_canonicalize3(in %a: i1, in %b: i1, out result : i1) {
|
|
%c0_i1 = hw.constant 0 : i1
|
|
%0 = comb.mux %a, %b, %c0_i1 : i1
|
|
hw.output %0 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @icmp_fold_1bit_eq1
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: %0 = comb.xor %arg, %true : i1
|
|
// CHECK-NEXT: %1 = comb.xor %arg, %true : i1
|
|
// CHECK-NEXT: hw.output %0, %arg, %arg, %1 : i1, i1, i1, i1
|
|
// CHECK-NEXT: }
|
|
hw.module @icmp_fold_1bit_eq1(in %arg: i1, out result : i1, out a: i1, out b: i1, out c: i1) {
|
|
%zero = hw.constant 0 : i1
|
|
%one = hw.constant 1 : i1
|
|
%0 = comb.icmp eq %zero, %arg : i1
|
|
%1 = comb.icmp eq %one, %arg : i1
|
|
%2 = comb.icmp ne %zero, %arg : i1
|
|
%3 = comb.icmp ne %one, %arg : i1
|
|
hw.output %0, %1, %2, %3 : i1, i1, i1, i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @sub_fold1
|
|
// CHECK-NEXT: %c-1_i7 = hw.constant -1 : i7
|
|
// CHECK-NEXT: hw.output %c-1_i7 : i7
|
|
hw.module @sub_fold1(in %arg0 : i7, out result : i7) {
|
|
%c11_i7 = hw.constant 11 : i7
|
|
%c5_i7 = hw.constant 12: i7
|
|
%0 = comb.sub %c11_i7, %c5_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @sub_fold2
|
|
// CHECK-NEXT: hw.output %arg0 : i7
|
|
hw.module @sub_fold2(in %arg0 : i7, out result : i7) {
|
|
%c0_i7 = hw.constant 0 : i7
|
|
%0 = comb.sub %arg0, %c0_i7 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @sub_fold3
|
|
// CHECK-NEXT: %c0_i7 = hw.constant 0 : i7
|
|
// CHECK-NEXT: hw.output %c0_i7 : i7
|
|
hw.module @sub_fold3(in %arg0 : i7, out result : i7) {
|
|
%0 = comb.sub %arg0, %arg0 : i7
|
|
hw.output %0 : i7
|
|
}
|
|
|
|
// CHECK-LABEL: issue955
|
|
// Incorrect constant folding with >64 bit constants.
|
|
hw.module @issue955(out result : i100, out a: i100) {
|
|
// 1 << 64
|
|
%0 = hw.constant 18446744073709551616 : i100
|
|
%1 = comb.and %0, %0 : i100
|
|
|
|
// CHECK-DAG: = hw.constant 18446744073709551616 : i100
|
|
|
|
// (1 << 64) + 1
|
|
%2 = hw.constant 18446744073709551617 : i100
|
|
%3 = comb.and %2, %2 : i100
|
|
|
|
// CHECK-DAG: = hw.constant 18446744073709551617 : i100
|
|
hw.output %1, %3 : i100, i100
|
|
}
|
|
|
|
// CHECK-LABEL: replicate_and_one_bit
|
|
hw.module @replicate_and_one_bit(in %bit: i1, out a: i65, out b: i8, out c: i8) {
|
|
%c-18446744073709551616_i65 = hw.constant -18446744073709551616 : i65
|
|
%0 = comb.replicate %bit : (i1) -> i65
|
|
%1 = comb.and %0, %c-18446744073709551616_i65 : i65
|
|
// CHECK: [[A:%[0-9]+]] = comb.concat %bit, %c0_i64 : i1, i64
|
|
|
|
%c4_i8 = hw.constant 4 : i8
|
|
%2 = comb.replicate %bit : (i1) -> i8
|
|
%3 = comb.and %2, %c4_i8 : i8
|
|
// CHECK: [[B:%[0-9]+]] = comb.concat %c0_i5, %bit, %c0_i2 : i5, i1, i2
|
|
|
|
%c1_i8 = hw.constant 1 : i8
|
|
%4 = comb.and %2, %c1_i8 : i8
|
|
// CHECK: [[C:%[0-9]+]] = comb.concat %c0_i7, %bit : i7, i1
|
|
|
|
// CHECK: hw.output [[A]], [[B]], [[C]] :
|
|
hw.output %1, %3, %4 : i65, i8, i8
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire0()
|
|
// CHECK-NEXT: hw.output
|
|
hw.module @wire0() {
|
|
%0 = sv.wire : !hw.inout<i1>
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire1()
|
|
// CHECK-NEXT: hw.output
|
|
hw.module @wire1() {
|
|
%0 = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %0 : !hw.inout<i1>
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire2()
|
|
// CHECK-NEXT: hw.output
|
|
hw.module @wire2() {
|
|
%c = hw.constant 1 : i1
|
|
%0 = sv.wire : !hw.inout<i1>
|
|
sv.assign %0, %c : i1
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire3()
|
|
// CHECK-NEXT: hw.output
|
|
hw.module @wire3() {
|
|
%c = hw.constant 1 : i1
|
|
%0 = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %0 : !hw.inout<i1>
|
|
sv.assign %0, %c :i1
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire4
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: %0 = sv.wire sym @symName : !hw.inout<i1>
|
|
// CHECK-NEXT: %1 = sv.read_inout %0 : !hw.inout<i1>
|
|
// CHECK-NEXT: sv.assign %0, %true : i1
|
|
// CHECK-NEXT: hw.output %1 : i1
|
|
hw.module @wire4(out result : i1) {
|
|
%true = hw.constant true
|
|
%0 = sv.wire sym @symName : !hw.inout<i1>
|
|
%1 = sv.read_inout %0 : !hw.inout<i1>
|
|
sv.assign %0, %true : i1
|
|
hw.output %1 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire4_1
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: hw.output %true : i1
|
|
hw.module @wire4_1(out result : i1) {
|
|
%true = hw.constant true
|
|
%0 = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %0 : !hw.inout<i1>
|
|
sv.assign %0, %true : i1
|
|
hw.output %1 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @wire5()
|
|
// CHECK-NEXT: %wire_with_name = sv.wire sym @wire_with_name : !hw.inout<i1>
|
|
// CHECK-NEXT: hw.output
|
|
hw.module @wire5() {
|
|
%wire_with_name = sv.wire sym @wire_with_name : !hw.inout<i1>
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @replicate
|
|
hw.module @replicate(in %arg0 : i7, out r1: i9, out r2: i7) {
|
|
%c2 = hw.constant 2 : i3
|
|
%r1 = comb.replicate %c2 : (i3) -> i9
|
|
|
|
// CHECK-NEXT: %c146_i9 = hw.constant 146 : i9
|
|
%r2 = comb.replicate %arg0 : (i7) -> i7
|
|
|
|
// CHECK-NEXT: hw.output %c146_i9, %arg0
|
|
hw.output %r1, %r2 : i9, i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @bitcast_canonicalization
|
|
hw.module @bitcast_canonicalization(in %arg0 : i4, out r1: i4, out r2: !hw.array<2xi2>) {
|
|
%id = hw.bitcast %arg0 : (i4) -> i4
|
|
%a = hw.bitcast %arg0 : (i4) -> !hw.struct<a:i2, b:i2>
|
|
%b = hw.bitcast %a : (!hw.struct<a:i2, b:i2>) -> !hw.array<2xi2>
|
|
// CHECK-NEXT: %0 = hw.bitcast %arg0 : (i4) -> !hw.array<2xi2>
|
|
// CHECK-NEXT: hw.output %arg0, %0
|
|
hw.output %id, %b : i4, !hw.array<2xi2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @array_create
|
|
// CHECK-NEXT: %0 = hw.aggregate_constant [0 : i2, 1 : i2, 0 : i2] : !hw.array<3xi2>
|
|
// CHECK-NEXT: hw.output %0 : !hw.array<3xi2
|
|
hw.module @array_create(out r0: !hw.array<3xi2>) {
|
|
%false = hw.constant 0 : i2
|
|
%true = hw.constant 1 : i2
|
|
%arr = hw.array_create %false, %true, %false : i2
|
|
hw.output %arr : !hw.array<3xi2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @array_get0
|
|
// CHECK-NEXT: %c-1_i2 = hw.constant -1 : i2
|
|
// CHECK-NEXT: hw.output %c-1_i2 : i2
|
|
hw.module @array_get0(in %index : i2, out r0: i2) {
|
|
%array = hw.aggregate_constant [3 : i2, 3 : i2, 3 : i2, 3 : i2] : !hw.array<4xi2>
|
|
%result = hw.array_get %array[%index] : !hw.array<4xi2>, i2
|
|
hw.output %result : i2
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @array_get1
|
|
// CHECK-NEXT: hw.output %a0 : i3
|
|
hw.module @array_get1(in %a0: i3, in %a1: i3, in %a2: i3, out r0: i3) {
|
|
%c0 = hw.constant 0 : i2
|
|
%arr = hw.array_create %a2, %a1, %a0 : i3
|
|
%r0 = hw.array_get %arr[%c0] : !hw.array<3xi3>, i2
|
|
hw.output %r0 : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_create
|
|
// CHECK-NEXT: %0 = hw.aggregate_constant [0 : i2, 1 : i2, 0 : i2] : !hw.struct<a: i2, b: i2, c: i2>
|
|
// CHECK-NEXT: hw.output %0 : !hw.struct<a: i2, b: i2, c: i2>
|
|
hw.module @struct_create(out r0: !hw.struct<a: i2, b: i2, c : i2>) {
|
|
%false = hw.constant 0 : i2
|
|
%true = hw.constant 1 : i2
|
|
%arr = hw.struct_create (%false, %true, %false) : !hw.struct<a: i2, b: i2, c : i2>
|
|
hw.output %arr : !hw.struct<a: i2, b: i2, c : i2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_create1
|
|
hw.module @struct_create1(in %in: !hw.struct<a: i2, b: i2, c: i2>, in %in1: i2, out r0: !hw.struct<a: i2, b: i2, c: i2>, out r1: !hw.struct<a: i2, b: i2, d: i2>, out r2: !hw.struct<a: i2, b: i2, c: i2>) {
|
|
// CHECK-NEXT: %a, %b, %c = hw.struct_explode %in : !hw.struct<a: i2, b: i2, c: i2>
|
|
%a, %b, %c = hw.struct_explode %in : !hw.struct<a: i2, b: i2, c: i2>
|
|
%1 = hw.struct_create (%a, %b, %c) : !hw.struct<a: i2, b: i2, c: i2>
|
|
// CHECK-NEXT: [[V1:%.+]] = hw.struct_create (%a, %b, %c) : !hw.struct<a: i2, b: i2, d: i2>
|
|
%2 = hw.struct_create (%a, %b, %c) : !hw.struct<a: i2, b: i2, d: i2>
|
|
// CHECK-NEXT: [[V2:%.+]] = hw.struct_create (%a, %b, %in1) : !hw.struct<a: i2, b: i2, c: i2>
|
|
%3 = hw.struct_create (%a, %b, %in1) : !hw.struct<a: i2, b: i2, c: i2>
|
|
// CHECK-NEXT: hw.output %in, [[V1]], [[V2]] : !hw.struct<a: i2, b: i2, c: i2>, !hw.struct<a: i2, b: i2, d: i2>, !hw.struct<a: i2, b: i2, c: i2>
|
|
hw.output %1, %2, %3 : !hw.struct<a: i2, b: i2, c: i2>, !hw.struct<a: i2, b: i2, d: i2>, !hw.struct<a: i2, b: i2, c: i2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_extract1
|
|
// CHECK-NEXT: hw.output %a0 : i3
|
|
hw.module @struct_extract1(in %a0: i3, in %a1: i5, out r0: i3) {
|
|
%s = hw.struct_create (%a0, %a1) : !hw.struct<foo: i3, bar: i5>
|
|
%r0 = hw.struct_extract %s["foo"] : !hw.struct<foo: i3, bar: i5>
|
|
hw.output %r0 : i3
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_extract2
|
|
// CHECK-NEXT: %c1_i3 = hw.constant 1 : i3
|
|
// CHECK-NEXT: %c3_i7 = hw.constant 3 : i7
|
|
// CHECK-NEXT: hw.output %c1_i3, %c3_i7 : i3, i7
|
|
hw.module @struct_extract2(out r0: i3, out r1: i7) {
|
|
%s = hw.aggregate_constant [1 : i3, [3 : i7]] : !hw.struct<foo: i3, bar: !hw.struct<baz: i7>>
|
|
%r0 = hw.struct_extract %s["foo"] : !hw.struct<foo: i3, bar: !hw.struct<baz: i7>>
|
|
%nested = hw.struct_extract %s["bar"] : !hw.struct<foo: i3, bar: !hw.struct<baz: i7>>
|
|
%r1 = hw.struct_extract %nested["baz"] : !hw.struct<baz: i7>
|
|
hw.output %r0, %r1 : i3, i7
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_explode0
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: hw.output %c0_i2 : i2
|
|
hw.module @struct_explode0(in %a0: i3, in %a1: i5, out r0: i2) {
|
|
%struct = hw.aggregate_constant [0 : i2, 1 : i2] : !hw.struct<a: i2, b: i2>
|
|
%r0:2 = hw.struct_explode %struct : !hw.struct<a: i2, b: i2>
|
|
hw.output %r0#0 : i2
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @struct_explode1
|
|
// CHECK-NEXT: hw.output %a0 : i3
|
|
hw.module @struct_explode1(in %a0: i3, in %a1: i5, out r0: i3) {
|
|
%s = hw.struct_create (%a0, %a1) : !hw.struct<foo: i3, bar: i5>
|
|
%r0:2 = hw.struct_explode %s : !hw.struct<foo: i3, bar: i5>
|
|
hw.output %r0#0 : i3
|
|
}
|
|
|
|
// Ensure that canonicalizer works with hw.enum.constant.
|
|
|
|
hw.module @enum_constant() {
|
|
%0 = hw.enum.constant A : !hw.enum<A, B, C>
|
|
}
|
|
|
|
|
|
// == Begin: test cases from LowerToHW ==
|
|
|
|
// CHECK-LABEL: hw.module @instance_ooo
|
|
// CHECK-NEXT: %false = hw.constant false
|
|
// CHECK-NEXT: %myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %3: i1) -> (out: i8) {oldParameters = {DEFAULT = 0 : i64, DEPTH = 3.242000e+01 : f64, FORMAT = "xyz_timeout=%d\0A", WIDTH = 32 : i8}}
|
|
// CHECK-NEXT: %0 = comb.concat %false, %arg0 : i1, i2
|
|
// CHECK-NEXT: %1 = comb.concat %false, %arg0 : i1, i2
|
|
// CHECK-NEXT: %2 = comb.add %0, %1 : i3
|
|
// CHECK-NEXT: %3 = comb.icmp eq %2, %arg2 {sv.namehint = ".in.wire"} : i3
|
|
// CHECK-NEXT: hw.output %myext.out : i8
|
|
|
|
hw.module @instance_ooo(in %arg0 : i2, in %arg1 : i2, in %arg2 : i3, out out0: i8) {
|
|
%false = hw.constant false
|
|
%.in.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.in.wire : !hw.inout<i1>
|
|
%myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %0: i1) -> (out: i8) {oldParameters = {DEFAULT = 0 : i64, DEPTH = 3.242000e+01 : f64, FORMAT = "xyz_timeout=%d\0A", WIDTH = 32 : i8}}
|
|
%1 = comb.concat %false, %arg0 : i1, i2
|
|
%2 = comb.concat %false, %arg0 : i1, i2
|
|
%3 = comb.add %1, %2 : i3
|
|
%4 = comb.icmp eq %3, %arg2 : i3
|
|
sv.assign %.in.wire, %4 : i1
|
|
hw.output %myext.out : i8
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @TestInstance
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: hw.instance "xyz" @Simple(in1: %0: i4, in2: %u2: i2, in3: %s8: i8)
|
|
// CHECK-NEXT: %0 = comb.concat %c0_i2, %u2 {sv.namehint = ".in1.wire"} : i2, i2
|
|
// CHECK-NEXT: %myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %reset: i1) -> (out: i8) {oldParameters = {DEFAULT = 0 : i64, DEPTH = 3.242000e+01 : f64, FORMAT = "xyz_timeout=%d\0A", WIDTH = 32 : i8}}
|
|
// CHECK-NEXT: hw.output
|
|
hw.module.extern @MyParameterizedExtModule(in %in: i1, out out: i8) attributes {verilogName = "name_thing"}
|
|
hw.module.extern @Simple(in %in1: i4, in %in2: i2, in %in3: i8)
|
|
hw.module @TestInstance(in %u2: i2, in %s8: i8, in %clock: i1, in %reset: i1) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%.in1.wire = sv.wire : !hw.inout<i4>
|
|
%0 = sv.read_inout %.in1.wire : !hw.inout<i4>
|
|
%.in2.wire = sv.wire : !hw.inout<i2>
|
|
%1 = sv.read_inout %.in2.wire : !hw.inout<i2>
|
|
%.in3.wire = sv.wire : !hw.inout<i8>
|
|
%2 = sv.read_inout %.in3.wire : !hw.inout<i8>
|
|
hw.instance "xyz" @Simple(in1: %0: i4, in2: %1: i2, in3: %2: i8) -> ()
|
|
%3 = comb.concat %c0_i2, %u2 : i2, i2
|
|
sv.assign %.in1.wire, %3 : i4
|
|
sv.assign %.in2.wire, %u2 : i2
|
|
sv.assign %.in3.wire, %s8 : i8
|
|
%.in.wire = sv.wire : !hw.inout<i1>
|
|
%4 = sv.read_inout %.in.wire : !hw.inout<i1>
|
|
%myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %4: i1) -> (out: i8) {oldParameters = {DEFAULT = 0 : i64, DEPTH = 3.242000e+01 : f64, FORMAT = "xyz_timeout=%d\0A", WIDTH = 32 : i8}}
|
|
sv.assign %.in.wire, %reset : i1
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @instance_cyclic
|
|
// CHECK-NEXT: %myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %0: i1)
|
|
// CHECK-NEXT: %0 = comb.extract %myext.out from 2
|
|
// CHECK-NEXT: hw.output
|
|
// CHECK-NEXT: }
|
|
hw.module @instance_cyclic(in %arg0 : i2, in %arg1 : i2) {
|
|
%.in.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.in.wire : !hw.inout<i1>
|
|
%myext.out = hw.instance "myext" @MyParameterizedExtModule(in: %0: i1) -> (out: i8) {oldParameters = {DEFAULT = 0 : i64, DEPTH = 3.242000e+01 : f64, FORMAT = "xyz_timeout=%d\0A", WIDTH = 32 : i8}}
|
|
%1 = comb.extract %myext.out from 2 : (i8) -> i1
|
|
sv.assign %.in.wire, %1 : i1
|
|
hw.output
|
|
}
|
|
|
|
hw.module.extern @ZeroWidthPorts(in %inA: i4, out outa: i4)
|
|
// CHECK-LABEL: hw.module @ZeroWidthInstance
|
|
// CHECK-NEXT: %myinst.outa = hw.instance "myinst" @ZeroWidthPorts(inA: %iA: i4) -> (outa: i4)
|
|
// CHECK-NEXT: hw.output %myinst.outa : i4
|
|
// CHECK-NEXT: }
|
|
hw.module @ZeroWidthInstance(in %iA: i4, out oA: i4) {
|
|
%.inA.wire = sv.wire : !hw.inout<i4>
|
|
%0 = sv.read_inout %.inA.wire : !hw.inout<i4>
|
|
%myinst.outa = hw.instance "myinst" @ZeroWidthPorts(inA: %0: i4) -> (outa: i4)
|
|
sv.assign %.inA.wire, %iA : i4
|
|
hw.output %myinst.outa : i4
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @unintializedWire
|
|
// CHECK-NEXT: %c0_i4 = hw.constant 0 : i4
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: %_M.ro_data_0, %_M.rw_data_0 = hw.instance "_M" @FIRRTLMem_1_1_1_42_12_0_1_0(ro_clock_0: %clock1: i1, ro_en_0: %true: i1, ro_addr_0: %c0_i4: i4) -> (ro_data_0: i42, rw_data_0: i42)
|
|
// CHECK-NEXT: hw.output %_M.ro_data_0, %_M.rw_data_0 : i42, i42
|
|
// CHECK-NEXT: }
|
|
hw.module.extern @FIRRTLMem_1_1_1_42_12_0_1_0(in %ro_clock_0: i1, in %ro_en_0: i1, in %ro_addr_0: i4, out ro_data_0: i42, out rw_data_0: i42)
|
|
hw.module @unintializedWire(in %clock1: i1, in %clock2: i1, in %inpred: i1, in %indata: i42, out result : i42, out result2: i42) {
|
|
%c0_i3 = hw.constant 0 : i3
|
|
%true = hw.constant true
|
|
%false = hw.constant false
|
|
%.read.clk.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.read.clk.wire : !hw.inout<i1>
|
|
%.read.en.wire = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %.read.en.wire : !hw.inout<i1>
|
|
%.read.addr.wire = sv.wire : !hw.inout<i4>
|
|
%2 = sv.read_inout %.read.addr.wire : !hw.inout<i4>
|
|
%.rw.clk.wire = sv.wire : !hw.inout<i1>
|
|
%3 = sv.read_inout %.rw.clk.wire : !hw.inout<i1>
|
|
%.rw.en.wire = sv.wire : !hw.inout<i1>
|
|
%4 = sv.read_inout %.rw.en.wire : !hw.inout<i1>
|
|
%.rw.addr.wire = sv.wire : !hw.inout<i4>
|
|
%5 = sv.read_inout %.rw.addr.wire : !hw.inout<i4>
|
|
%.rw.wmode.wire = sv.wire : !hw.inout<i1>
|
|
%6 = sv.read_inout %.rw.wmode.wire : !hw.inout<i1>
|
|
%.rw.wmask.wire = sv.wire : !hw.inout<i1>
|
|
%7 = sv.read_inout %.rw.wmask.wire : !hw.inout<i1>
|
|
%.rw.wdata.wire = sv.wire : !hw.inout<i42>
|
|
%8 = sv.read_inout %.rw.wdata.wire : !hw.inout<i42>
|
|
%.write.clk.wire = sv.wire : !hw.inout<i1>
|
|
%9 = sv.read_inout %.write.clk.wire : !hw.inout<i1>
|
|
%.write.en.wire = sv.wire : !hw.inout<i1>
|
|
%10 = sv.read_inout %.write.en.wire : !hw.inout<i1>
|
|
%.write.addr.wire = sv.wire : !hw.inout<i4>
|
|
%11 = sv.read_inout %.write.addr.wire : !hw.inout<i4>
|
|
%.write.mask.wire = sv.wire : !hw.inout<i1>
|
|
%12 = sv.read_inout %.write.mask.wire : !hw.inout<i1>
|
|
%.write.data.wire = sv.wire : !hw.inout<i42>
|
|
%13 = sv.read_inout %.write.data.wire : !hw.inout<i42>
|
|
%_M.ro_data_0, %_M.rw_rdata_0 = hw.instance "_M" @FIRRTLMem_1_1_1_42_12_0_1_0
|
|
(ro_clock_0: %0: i1, ro_en_0: %1: i1, ro_addr_0: %2: i4) -> (ro_data_0: i42, rw_data_0: i42)
|
|
|
|
%14 = sv.read_inout %.read.addr.wire : !hw.inout<i4>
|
|
%c0_i4 = hw.constant 0 : i4
|
|
sv.assign %.read.addr.wire, %c0_i4 : i4
|
|
%15 = sv.read_inout %.read.en.wire : !hw.inout<i1>
|
|
sv.assign %.read.en.wire, %true : i1
|
|
%16 = sv.read_inout %.read.clk.wire : !hw.inout<i1>
|
|
sv.assign %.read.clk.wire, %clock1 : i1
|
|
%17 = sv.read_inout %.rw.addr.wire : !hw.inout<i4>
|
|
%c0_i4_0 = hw.constant 0 : i4
|
|
sv.assign %.rw.addr.wire, %c0_i4_0 : i4
|
|
%18 = sv.read_inout %.rw.en.wire : !hw.inout<i1>
|
|
sv.assign %.rw.en.wire, %true : i1
|
|
%19 = sv.read_inout %.rw.clk.wire : !hw.inout<i1>
|
|
sv.assign %.rw.clk.wire, %clock1 : i1
|
|
%20 = sv.read_inout %.rw.wmask.wire : !hw.inout<i1>
|
|
sv.assign %.rw.wmask.wire, %true : i1
|
|
%21 = sv.read_inout %.rw.wmode.wire : !hw.inout<i1>
|
|
sv.assign %.rw.wmode.wire, %true : i1
|
|
%22 = sv.read_inout %.write.addr.wire : !hw.inout<i4>
|
|
%c0_i4_1 = hw.constant 0 : i4
|
|
sv.assign %.write.addr.wire, %c0_i4_1 : i4
|
|
%23 = sv.read_inout %.write.en.wire : !hw.inout<i1>
|
|
sv.assign %.write.en.wire, %inpred : i1
|
|
%24 = sv.read_inout %.write.clk.wire : !hw.inout<i1>
|
|
sv.assign %.write.clk.wire, %clock2 : i1
|
|
%25 = sv.read_inout %.write.data.wire : !hw.inout<i42>
|
|
sv.assign %.write.data.wire, %indata : i42
|
|
%26 = sv.read_inout %.write.mask.wire : !hw.inout<i1>
|
|
sv.assign %.write.mask.wire, %true : i1
|
|
hw.output %_M.ro_data_0, %_M.rw_rdata_0 : i42, i42
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @uninitializedWireAggregate
|
|
hw.module @uninitializedWireAggregate(out result1: !hw.struct<a: i1, b: i1>,
|
|
out result2: !hw.struct<a: i1, b: !hw.array<10x!hw.struct<a: i1, b: i1>>>)
|
|
{
|
|
%0 = sv.wire : !hw.inout<!hw.struct<a: i1, b: i1>>
|
|
%1 = sv.read_inout %0 : !hw.inout<!hw.struct<a: i1, b: i1>>
|
|
%2 = sv.wire : !hw.inout<!hw.struct<a: i1, b: !hw.array<10x!hw.struct<a: i1, b: i1>>>>
|
|
%3 = sv.read_inout %2 : !hw.inout<!hw.struct<a: i1, b: !hw.array<10x!hw.struct<a: i1, b: i1>>>>
|
|
|
|
hw.output %1, %3 : !hw.struct<a: i1, b: i1>, !hw.struct<a: i1, b: !hw.array<10x!hw.struct<a: i1, b: i1>>>
|
|
// CHECK-NEXT: %[[Z1:.*]] = sv.constantZ : !hw.struct<a: i1, b: i1>
|
|
// CHECK-NEXT: %[[Z2:.*]] = sv.constantZ : !hw.struct<a: i1, b: !hw.array<10xstruct<a: i1, b: i1>>>
|
|
// CHECK-NEXT: hw.output %[[Z1]], %[[Z2]]
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @IncompleteRead
|
|
// CHECK-NEXT: %c0_i4 = hw.constant 0 : i4
|
|
// CHECK-NEXT: %true = hw.constant true
|
|
// CHECK-NEXT: %_M.ro_data_0 = hw.instance "_M" @FIRRTLMem_1_0_0_42_12_0_1_0(ro_clock_0: %clock1: i1, ro_en_0: %true: i1, ro_addr_0: %c0_i4: i4) -> (ro_data_0: i42)
|
|
// CHECK-NEXT: hw.output
|
|
// CHECK-NEXT: }
|
|
hw.module.extern @FIRRTLMem_1_0_0_42_12_0_1_0(in %ro_clock_0: i1, in %ro_en_0: i1, in %ro_addr_0: i4, out ro_data_0: i42)
|
|
hw.module @IncompleteRead(in %clock1: i1) {
|
|
%c0_i3 = hw.constant 0 : i3
|
|
%true = hw.constant true
|
|
%false = hw.constant false
|
|
%.read.clk.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.read.clk.wire : !hw.inout<i1>
|
|
%.read.en.wire = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %.read.en.wire : !hw.inout<i1>
|
|
%.read.addr.wire = sv.wire : !hw.inout<i4>
|
|
%2 = sv.read_inout %.read.addr.wire : !hw.inout<i4>
|
|
%_M.ro_data_0 = hw.instance "_M" @FIRRTLMem_1_0_0_42_12_0_1_0(ro_clock_0: %0: i1, ro_en_0: %1: i1, ro_addr_0: %2: i4) -> (ro_data_0: i42)
|
|
%3 = sv.read_inout %.read.addr.wire : !hw.inout<i4>
|
|
%c0_i4 = hw.constant 0 : i4
|
|
sv.assign %.read.addr.wire, %c0_i4 : i4
|
|
%4 = sv.read_inout %.read.en.wire : !hw.inout<i1>
|
|
sv.assign %.read.en.wire, %true : i1
|
|
%5 = sv.read_inout %.read.clk.wire : !hw.inout<i1>
|
|
sv.assign %.read.clk.wire, %clock1 : i1
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @foo() {
|
|
// CHECK-NEXT: %io_cpu_flush.wire = sv.wire sym @io_cpu_flush.wire : !hw.inout<i1>
|
|
// CHECK-NEXT: hw.instance "fetch" @bar(io_cpu_flush: %0: i1) -> ()
|
|
// CHECK-NEXT: %0 = sv.read_inout %io_cpu_flush.wire {sv.namehint = ".io_cpu_flush.wire"}
|
|
// CHECK-NEXT: hw.output
|
|
hw.module.extern @bar(in %io_cpu_flush: i1)
|
|
hw.module @foo() {
|
|
%io_cpu_flush.wire = sv.wire sym @io_cpu_flush.wire : !hw.inout<i1>
|
|
%.io_cpu_flush.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.io_cpu_flush.wire : !hw.inout<i1>
|
|
hw.instance "fetch" @bar(io_cpu_flush: %0: i1) -> ()
|
|
%1 = sv.read_inout %io_cpu_flush.wire : !hw.inout<i1>
|
|
sv.assign %.io_cpu_flush.wire, %1 : i1
|
|
%2 = sv.read_inout %io_cpu_flush.wire : !hw.inout<i1>
|
|
%hits_1_7 = sv.wire : !hw.inout<i1>
|
|
sv.assign %hits_1_7, %2 : i1
|
|
hw.output
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @MemDepth1
|
|
// CHECK-NEXT: %mem0.0 = hw.instance "mem0" @FIRRTLMem_1_0_0_32_1_0_1_1(x: %clock: i1, y: %en: i1, z: %addr: i1) -> ("": i32)
|
|
// CHECK-NEXT: hw.output %mem0.0 : i32
|
|
// CHECK-NEXT: }
|
|
hw.module.extern @FIRRTLMem_1_0_0_32_1_0_1_1(in %x: i1, in %y: i1, in %z: i1, out "": i32)
|
|
hw.module @MemDepth1(in %clock: i1, in %en: i1, in %addr: i1, out data: i32) {
|
|
%.load0.clk.wire = sv.wire : !hw.inout<i1>
|
|
%0 = sv.read_inout %.load0.clk.wire : !hw.inout<i1>
|
|
%.load0.en.wire = sv.wire : !hw.inout<i1>
|
|
%1 = sv.read_inout %.load0.en.wire : !hw.inout<i1>
|
|
%.load0.addr.wire = sv.wire : !hw.inout<i1>
|
|
%2 = sv.read_inout %.load0.addr.wire : !hw.inout<i1>
|
|
%mem0.ro_data_0 = hw.instance "mem0" @FIRRTLMem_1_0_0_32_1_0_1_1("x": %0: i1, "y": %1: i1, "z": %2: i1) -> ("": i32)
|
|
%3 = sv.read_inout %.load0.clk.wire : !hw.inout<i1>
|
|
sv.assign %.load0.clk.wire, %clock : i1
|
|
%4 = sv.read_inout %.load0.addr.wire : !hw.inout<i1>
|
|
sv.assign %.load0.addr.wire, %addr : i1
|
|
%5 = sv.read_inout %.load0.en.wire : !hw.inout<i1>
|
|
sv.assign %.load0.en.wire, %en : i1
|
|
hw.output %mem0.ro_data_0 : i32
|
|
}
|
|
|
|
// == End: test cases from LowerToHW ==
|
|
|
|
// CHECK-LABEL: hw.module @ExtractOfInject
|
|
hw.module @ExtractOfInject(in %a: !hw.struct<a: i1>, in %v: i1, out result : i1) {
|
|
%b = hw.struct_inject %a["a"], %v : !hw.struct<a: i1>
|
|
%c = hw.struct_extract %b["a"] : !hw.struct<a: i1>
|
|
// CHECK: hw.output %v
|
|
hw.output %c : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @ExtractCycle
|
|
hw.module @ExtractCycle(in %a: !hw.struct<a: i1>, in %v: i1, out result : i1) {
|
|
%b = hw.struct_inject %b["a"], %v : !hw.struct<a: i1>
|
|
%c = hw.struct_extract %b["a"] : !hw.struct<a: i1>
|
|
// CHECK: hw.output %v
|
|
hw.output %c : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @ExtractOfUnrelatedInject
|
|
hw.module @ExtractOfUnrelatedInject(in %a: !hw.struct<a: i1, b: i1>, in %v: i1, out result : i1) {
|
|
%b = hw.struct_inject %a["b"], %v : !hw.struct<a: i1, b: i1>
|
|
%c = hw.struct_extract %b["a"] : !hw.struct<a: i1, b: i1>
|
|
// CHECK: [[STRUCT:%.+]] = hw.struct_extract %a["a"] : !hw.struct<a: i1, b: i1>
|
|
// CHECK-NEXT: hw.output [[STRUCT]]
|
|
hw.output %c : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @InjectOnConstant
|
|
hw.module @InjectOnConstant(out result : !hw.struct<a: i2>) {
|
|
%struct = hw.aggregate_constant [0 : i2] : !hw.struct<a: i2>
|
|
%c1_i2 = hw.constant 1 : i2
|
|
%result = hw.struct_inject %struct["a"], %c1_i2 : !hw.struct<a: i2>
|
|
// CHECK: [[STRUCT:%.+]] = hw.aggregate_constant [1 : i2] : !hw.struct<a: i2>
|
|
// CHECK-NEXT: hw.output [[STRUCT]]
|
|
hw.output %result : !hw.struct<a: i2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @InjectOnInject
|
|
hw.module @InjectOnInject(in %a: !hw.struct<a: i1>, in %p: i1, in %q: i1, out result : !hw.struct<a: i1>) {
|
|
%b = hw.struct_inject %a["a"], %p : !hw.struct<a: i1>
|
|
%c = hw.struct_inject %b["a"], %q : !hw.struct<a: i1>
|
|
// CHECK: [[STRUCT:%.+]] = hw.struct_create (%q) : !hw.struct<a: i1>
|
|
// CHECK-NEXT: hw.output [[STRUCT]]
|
|
hw.output %c : !hw.struct<a: i1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @InjectOnInjectChain
|
|
hw.module @InjectOnInjectChain(in %a: !hw.struct<a: i1, b: i1, c: i1>, in %p: i1, in %q: i1, in %s: i1, out result : !hw.struct<a: i1, b: i1, c: i1>) {
|
|
%b = hw.struct_inject %a["a"], %p : !hw.struct<a: i1, b: i1, c: i1>
|
|
%c = hw.struct_inject %b["a"], %q : !hw.struct<a: i1, b: i1, c: i1>
|
|
%d = hw.struct_inject %c["b"], %s : !hw.struct<a: i1, b: i1, c: i1>
|
|
// CHECK: [[A:%.+]] = hw.struct_inject %a["a"], %q : !hw.struct<a: i1, b: i1, c: i1>
|
|
// CHECK: [[B:%.+]] = hw.struct_inject %0["b"], %s : !hw.struct<a: i1, b: i1, c: i1>
|
|
// CHECK-NEXT: hw.output [[B]]
|
|
hw.output %d : !hw.struct<a: i1, b: i1, c: i1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @InjectToCreate
|
|
hw.module @InjectToCreate(in %a: !hw.struct<a: i1, b: i1>, in %p: i1, in %q: i1, out result : !hw.struct<a: i1, b: i1>) {
|
|
%b = hw.struct_inject %a["a"], %p : !hw.struct<a: i1, b: i1>
|
|
%c = hw.struct_inject %b["b"], %q : !hw.struct<a: i1, b: i1>
|
|
// CHECK: [[STRUCT:%.+]] = hw.struct_create (%p, %q) : !hw.struct<a: i1, b: i1>
|
|
// CHECK-NEXT: hw.output [[STRUCT]]
|
|
hw.output %c : !hw.struct<a: i1, b: i1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @GetOfConcat
|
|
hw.module @GetOfConcat(in %a: !hw.array<5xi1>, in %b: !hw.array<2xi1>, out out0: i1, out out1: i1) {
|
|
%concat = hw.array_concat %a, %b : !hw.array<5xi1>, !hw.array<2xi1>
|
|
%c1_i3 = hw.constant 1 : i3
|
|
%out0 = hw.array_get %concat[%c1_i3] : !hw.array<7xi1>, i3
|
|
%c6_i3 = hw.constant 6 : i3
|
|
%out1 = hw.array_get %concat[%c6_i3] : !hw.array<7xi1>, i3
|
|
// CHECK: [[OUT0:%.+]] = hw.array_get %b[%true] : !hw.array<2xi1>
|
|
// CHECK: [[OUT1:%.+]] = hw.array_get %a[%c-4_i3] : !hw.array<5xi1>
|
|
// CHECK: hw.output [[OUT0]], [[OUT1]] : i1, i1
|
|
hw.output %out0, %out1 : i1, i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @zeroLenArrSlice
|
|
// CHECK: = hw.array_slice %arg0[%c0_i2] : (!hw.array<4xi8>) -> !hw.array<0xi8>
|
|
hw.module @zeroLenArrSlice(in %arg0 : !hw.array<4xi8>, out "": !hw.array<0xi8>) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%x = hw.array_slice %arg0[%c0_i2] : (!hw.array<4xi8>) -> !hw.array<0xi8>
|
|
hw.output %x : !hw.array<0xi8>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @GetOfSliceStatic
|
|
hw.module @GetOfSliceStatic(in %a: !hw.array<5xi1>, out out0: i1) {
|
|
%c1_i3 = hw.constant 1 : i3
|
|
%c1_i2 = hw.constant 1 : i2
|
|
%slice = hw.array_slice %a[%c1_i3] : (!hw.array<5xi1>) -> !hw.array<3xi1>
|
|
%get = hw.array_get %slice[%c1_i2] : !hw.array<3xi1>, i2
|
|
|
|
// CHECK: [[OUT:%.+]] = hw.array_get %a[%c2_i3] : !hw.array<5xi1>
|
|
// CHECK: hw.output [[OUT]] : i1
|
|
hw.output %get : i1
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @ConcatOfConstants
|
|
hw.module @ConcatOfConstants(in %index: i2, out r0: !hw.array<2xi2>) {
|
|
%lhs = hw.aggregate_constant [3 : i2] : !hw.array<1xi2>
|
|
%rhs = hw.aggregate_constant [3 : i2] : !hw.array<1xi2>
|
|
%concat = hw.array_concat %lhs, %rhs : !hw.array<1xi2>, !hw.array<1xi2>
|
|
// CHECK: [[OUT:%.+]] = hw.aggregate_constant [-1 : i2, -1 : i2] : !hw.array<2xi2>
|
|
// CHECK: hw.output [[OUT]] : !hw.array<2xi2>
|
|
hw.output %concat : !hw.array<2xi2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @ConcatOfSingleElement
|
|
hw.module @ConcatOfSingleElement(in %i0: !hw.array<2xi2>, out r0: !hw.array<2xi2>) {
|
|
%r0 = hw.array_concat %i0 : !hw.array<2xi2>
|
|
// CHECK: hw.output %i0 : !hw.array<2xi2>
|
|
hw.output %r0 : !hw.array<2xi2>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @ConcatOfCreate
|
|
hw.module @ConcatOfCreate(in %a: i1, in %b: i1, out out0: !hw.array<5xi1>) {
|
|
%lhs = hw.array_create %a, %b : i1
|
|
%rhs = hw.array_create %a, %b, %a : i1
|
|
%concat = hw.array_concat %lhs, %rhs : !hw.array<2xi1>, !hw.array<3xi1>
|
|
// CHECK: [[ARRAY:%.+]] = hw.array_create %a, %b, %a, %b, %a : i1
|
|
// CHECK: hw.output [[ARRAY]] : !hw.array<5xi1>
|
|
hw.output %concat : !hw.array<5xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @SliceOfConcat
|
|
hw.module @SliceOfConcat(in %a: !hw.array<2xi1>, in %b: !hw.array<3xi1>, in %c: !hw.array<4xi1>, in %d: !hw.array<5xi1>, out out0: !hw.array<3xi1>, out out1: !hw.array<8xi1>, out out2: !hw.array<5xi1>) {
|
|
%concat = hw.array_concat %a, %b, %c, %d : !hw.array<2xi1>, !hw.array<3xi1>, !hw.array<4xi1>, !hw.array<5xi1>
|
|
|
|
%c0_i4 = hw.constant 0 : i4
|
|
%c3_i4 = hw.constant 3 : i4
|
|
%c7_i4 = hw.constant 7 : i4
|
|
|
|
%slice0 = hw.array_slice %concat[%c0_i4] : (!hw.array<14xi1>) -> !hw.array<3xi1>
|
|
%slice1 = hw.array_slice %concat[%c3_i4] : (!hw.array<14xi1>) -> !hw.array<8xi1>
|
|
%slice2 = hw.array_slice %concat[%c7_i4] : (!hw.array<14xi1>) -> !hw.array<5xi1>
|
|
|
|
// CHECK: [[SLICE_0:%.+]] = hw.array_slice %d[%c0_i3] : (!hw.array<5xi1>) -> !hw.array<3xi1>
|
|
// CHECK: [[D:%.+]] = hw.array_slice %d[%c3_i3] : (!hw.array<5xi1>) -> !hw.array<2xi1>
|
|
// CHECK: [[B:%.+]] = hw.array_slice %b[%c0_i2] : (!hw.array<3xi1>) -> !hw.array<2xi1>
|
|
// CHECK: [[SLICE_1:%.+]] = hw.array_concat [[B]], %c, [[D]] : !hw.array<2xi1>, !hw.array<4xi1>, !hw.array<2xi1>
|
|
// CHECK: [[C:%.+]] = hw.array_slice %c[%c-2_i2] : (!hw.array<4xi1>) -> !hw.array<2xi1>
|
|
// CHECK: [[SLICE_2:%.+]] = hw.array_concat %b, [[C]] : !hw.array<3xi1>, !hw.array<2xi1>
|
|
// CHECK: hw.output [[SLICE_0]], [[SLICE_1]], [[SLICE_2]] : !hw.array<3xi1>, !hw.array<8xi1>, !hw.array<5xi1>
|
|
|
|
|
|
hw.output %slice0, %slice1, %slice2 : !hw.array<3xi1>, !hw.array<8xi1>, !hw.array<5xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @SingleElementSlice
|
|
hw.module @SingleElementSlice(in %a: !hw.array<2xi1>, out out: !hw.array<1xi1>) {
|
|
%false = hw.constant 0 : i1
|
|
%out = hw.array_slice %a[%false] : (!hw.array<2xi1>) -> !hw.array<1xi1>
|
|
|
|
// CHECK: [[ELEM:%.+]] = hw.array_get %a[%false] : !hw.array<2xi1>
|
|
// CHECK: [[CREATE:%.+]] = hw.array_create [[ELEM]] : i1
|
|
// CHECK: hw.output [[CREATE]] : !hw.array<1xi1>
|
|
|
|
hw.output %out : !hw.array<1xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @SliceOfSlice
|
|
hw.module @SliceOfSlice(in %a: !hw.array<7xi1>, out out: !hw.array<2xi1>) {
|
|
%c1_i3 = hw.constant 1 : i3
|
|
|
|
%slice0 = hw.array_slice %a[%c1_i3] : (!hw.array<7xi1>) -> !hw.array<6xi1>
|
|
%slice1 = hw.array_slice %slice0[%c1_i3] : (!hw.array<6xi1>) -> !hw.array<2xi1>
|
|
|
|
// CHECK: [[SLICE:%.+]] = hw.array_slice %a[%c2_i3] : (!hw.array<7xi1>) -> !hw.array<2xi1>
|
|
// CHECK: hw.output [[SLICE]] : !hw.array<2xi1>
|
|
|
|
hw.output %slice1 : !hw.array<2xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @SliceOfCreate
|
|
hw.module @SliceOfCreate(in %a0: i1, in %a1: i1, in %a2: i1, in %a3: i1, out out: !hw.array<2xi1>) {
|
|
%c1_i2 = hw.constant 1 : i2
|
|
|
|
%create = hw.array_create %a3, %a2, %a1, %a0 : i1
|
|
%slice = hw.array_slice %create[%c1_i2] : (!hw.array<4xi1>) -> !hw.array<2xi1>
|
|
|
|
// CHECK: [[CREATE:%.+]] = hw.array_create %a2, %a1 : i1
|
|
// CHECK: hw.output [[CREATE]] : !hw.array<2xi1>
|
|
|
|
hw.output %slice : !hw.array<2xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @GetOfUniformArray
|
|
hw.module @GetOfUniformArray(in %in: i42, in %address: i2, out out: i42) {
|
|
// CHECK: hw.output %in : i42
|
|
%0 = hw.array_create %in, %in, %in, %in : i42
|
|
%1 = hw.array_get %0[%address] : !hw.array<4xi42>, i2
|
|
hw.output %1 : i42
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @GetOfConstantArray
|
|
hw.module @GetOfConstantArray(out b: i4) {
|
|
%c1_i2 = hw.constant 1 : i2
|
|
%c0_i16 = hw.constant 311 : i16
|
|
%0 = hw.bitcast %c0_i16 : (i16) -> !hw.array<4xi4>
|
|
// %0 = {0000, 0001, 0011, 0111}
|
|
%1 = hw.array_get %0[%c1_i2] : !hw.array<4xi4>, i2
|
|
// CHECK: hw.output %c3_i4
|
|
hw.output %1 : i4
|
|
}
|
|
|
|
// CHECK-LABEL: ArraySlice
|
|
hw.module @ArraySlice(in %arr: !hw.array<128xi1>, out a: !hw.array<128xi1>) {
|
|
%c0_i7 = hw.constant 0 : i7
|
|
// CHECK: hw.output %arr
|
|
%1 = hw.array_slice %arr[%c0_i7] : (!hw.array<128xi1>) -> !hw.array<128xi1>
|
|
hw.output %1 : !hw.array<128xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @CreateOfSlice
|
|
hw.module @CreateOfSlice(in %a: !hw.array<3xi1>, out out: !hw.array<2xi1>) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%c1_i2 = hw.constant 1 : i2
|
|
|
|
%a0 = hw.array_get %a[%c0_i2] : !hw.array<3xi1>, i2
|
|
%a1 = hw.array_get %a[%c1_i2] : !hw.array<3xi1>, i2
|
|
|
|
%create = hw.array_create %a1, %a0 : i1
|
|
|
|
// CHECK: [[SLICE:%.+]] = hw.array_slice %a[%c0_i2] : (!hw.array<3xi1>) -> !hw.array<2xi1>
|
|
// CHECK-NEXT: hw.output [[SLICE]] : !hw.array<2xi1>
|
|
|
|
hw.output %create : !hw.array<2xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @CreateOfSliceFull
|
|
hw.module @CreateOfSliceFull(in %a: !hw.array<3xi1>, out out: !hw.array<3xi1>) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%c1_i2 = hw.constant 1 : i2
|
|
%c2_i2 = hw.constant 2 : i2
|
|
|
|
%a0 = hw.array_get %a[%c0_i2] : !hw.array<3xi1>, i2
|
|
%a1 = hw.array_get %a[%c1_i2] : !hw.array<3xi1>, i2
|
|
%a2 = hw.array_get %a[%c2_i2] : !hw.array<3xi1>, i2
|
|
|
|
%create = hw.array_create %a2, %a1, %a0 : i1
|
|
|
|
// CHECK-NEXT: hw.output %a : !hw.array<3xi1>
|
|
|
|
hw.output %create : !hw.array<3xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: hw.module @CreateOfSlices
|
|
hw.module @CreateOfSlices(in %arr0: !hw.array<3xi1>, in %arr1: !hw.array<5xi1>, out res: !hw.array<6xi1>) {
|
|
%c3_i3 = hw.constant 3 : i3
|
|
%c2_i3 = hw.constant 2 : i3
|
|
%c1_i3 = hw.constant 1 : i3
|
|
%c0_i3 = hw.constant 0 : i3
|
|
%c2_i2 = hw.constant 2 : i2
|
|
%c1_i2 = hw.constant 1 : i2
|
|
|
|
%0 = hw.array_get %arr1[%c3_i3] : !hw.array<5xi1>, i3
|
|
%1 = hw.array_get %arr1[%c2_i3] : !hw.array<5xi1>, i3
|
|
%2 = hw.array_get %arr1[%c1_i3] : !hw.array<5xi1>, i3
|
|
%3 = hw.array_get %arr1[%c0_i3] : !hw.array<5xi1>, i3
|
|
%4 = hw.array_get %arr0[%c2_i2] : !hw.array<3xi1>, i2
|
|
%5 = hw.array_get %arr0[%c1_i2] : !hw.array<3xi1>, i2
|
|
%6 = hw.array_create %0, %1, %2, %3, %4, %5 : i1
|
|
|
|
// CHECK-DAG: [[ARR0:%.+]] = hw.array_slice %arr0[%c1_i2] : (!hw.array<3xi1>) -> !hw.array<2xi1>
|
|
// CHECK-DAG: [[ARR1:%.+]] = hw.array_slice %arr1[%c0_i3] : (!hw.array<5xi1>) -> !hw.array<4xi1>
|
|
// CHECK-DAG: [[CONCAT:%.+]] = hw.array_concat [[ARR1]], [[ARR0]] : !hw.array<4xi1>, !hw.array<2xi1>
|
|
// CHECK-DAG: hw.output [[CONCAT]] : !hw.array<6xi1>
|
|
hw.output %6 : !hw.array<6xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: @MuxOfArrays
|
|
hw.module @MuxOfArrays(in %cond: i1, in %a0: i1, in %a1: i1, in %a2: i1, in %b0: i1, in %b1: i1, in %b2: i1, out res: !hw.array<3xi1>) {
|
|
%mux0 = comb.mux %cond, %a0, %b0 : i1
|
|
%mux1 = comb.mux %cond, %a1, %b1 : i1
|
|
%mux2 = comb.mux %cond, %a2, %b2 : i1
|
|
%array = hw.array_create %mux2, %mux1, %mux0 : i1
|
|
|
|
// CHECK: [[TRUE:%.+]] = hw.array_create %a2, %a1, %a0 : i1
|
|
// CHECK-NEXT: [[FALSE:%.+]] = hw.array_create %b2, %b1, %b0 : i1
|
|
// CHECK-NEXT: [[RESULT:%.+]] = comb.mux %cond, [[TRUE]], [[FALSE]] : !hw.array<3xi1>
|
|
// CHECK-NEXT: hw.output [[RESULT]] : !hw.array<3xi1>
|
|
|
|
hw.output %array : !hw.array<3xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: @MuxOfUniformArray
|
|
hw.module @MuxOfUniformArray(in %cond: i1, in %a: i1, in %b: i1, out res: !hw.array<3xi1>) {
|
|
%array_a = hw.array_create %a, %a, %a : i1
|
|
%array_b = hw.array_create %b, %b, %b : i1
|
|
%mux = comb.mux %cond, %array_a, %array_b : !hw.array<3xi1>
|
|
|
|
// CHECK: [[MUX:%.+]] = comb.mux %cond, %a, %b : i1
|
|
// CHECK-NEXT: [[ARRAY:%.+]] = hw.array_create [[MUX]], [[MUX]], [[MUX]] : i1
|
|
// CHECK-NEXT: hw.output [[ARRAY]] : !hw.array<3xi1>
|
|
|
|
hw.output %mux : !hw.array<3xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: @ConcatOfSlicesAndGets
|
|
hw.module @ConcatOfSlicesAndGets(in %a: !hw.array<5xi1>, in %b: !hw.array<5xi1>, in %c: !hw.array<5xi1>, out res: !hw.array<13xi1>) {
|
|
%c1_i3 = hw.constant 1 : i3
|
|
%c3_i3 = hw.constant 3 : i3
|
|
%c4_i3 = hw.constant 4 : i3
|
|
|
|
%slice_a0 = hw.array_slice %a[%c1_i3] : (!hw.array<5xi1>) -> !hw.array<2xi1>
|
|
%slice_a1 = hw.array_slice %a[%c3_i3] : (!hw.array<5xi1>) -> !hw.array<1xi1>
|
|
%get_a = hw.array_get %a[%c4_i3] : !hw.array<5xi1>, i3
|
|
%wrap_a = hw.array_create %get_a : i1
|
|
|
|
%slice_b = hw.array_slice %b[%c1_i3] : (!hw.array<5xi1>) -> !hw.array<3xi1>
|
|
%get_b = hw.array_get %b[%c4_i3] : !hw.array<5xi1>, i3
|
|
%wrap_b = hw.array_create %get_b : i1
|
|
|
|
// CHECK-DAG: [[SLICE_A:%.+]] = hw.array_slice %a[%c1_i3] : (!hw.array<5xi1>) -> !hw.array<4xi1>
|
|
// CHECK-DAG: [[SLICE_B:%.+]] = hw.array_slice %b[%c1_i3] : (!hw.array<5xi1>) -> !hw.array<4xi1>
|
|
// CHECK-DAG: [[CONCAT:%.+]] = hw.array_concat %c, [[SLICE_B]], [[SLICE_A]] : !hw.array<5xi1>, !hw.array<4xi1>, !hw.array<4xi1>
|
|
// CHECK-DAG: hw.output [[CONCAT]] : !hw.array<13xi1>
|
|
%result = hw.array_concat %c, %wrap_b, %slice_b, %wrap_a, %slice_a1, %slice_a0 :
|
|
!hw.array<5xi1>, !hw.array<1xi1>, !hw.array<3xi1>, !hw.array<1xi1>, !hw.array<1xi1>, !hw.array<2xi1>
|
|
|
|
hw.output %result : !hw.array<13xi1>
|
|
}
|
|
|
|
// CHECK-LABEL: SwapConstantIndex
|
|
hw.module @SwapConstantIndex(in %a_0: !hw.array<4xi1>, in %a_1: !hw.array<4xi1>, in %a_2: !hw.array<4xi1>, in %a_3: !hw.array<4xi1>, in %sel: i2, out b: i1) {
|
|
%c0_i2 = hw.constant 0 : i2
|
|
%0 = hw.array_create %a_3, %a_2, %a_1, %a_0 : !hw.array<4xi1>
|
|
%1 = hw.array_get %0[%sel] : !hw.array<4xarray<4xi1>>, i2
|
|
%2 = hw.array_get %1[%c0_i2] : !hw.array<4xi1>, i2
|
|
hw.output %2 : i1
|
|
// CHECK-NEXT: %c0_i2 = hw.constant 0 : i2
|
|
// CHECK-NEXT: %0 = hw.array_get %a_3[%c0_i2] : !hw.array<4xi1>, i2
|
|
// CHECK-NEXT: %1 = hw.array_get %a_2[%c0_i2] : !hw.array<4xi1>, i2
|
|
// CHECK-NEXT: %2 = hw.array_get %a_1[%c0_i2] : !hw.array<4xi1>, i2
|
|
// CHECK-NEXT: %3 = hw.array_get %a_0[%c0_i2] : !hw.array<4xi1>, i2
|
|
// CHECK-NEXT: %4 = hw.array_create %0, %1, %2, %3 : i1
|
|
// CHECK-NEXT: %5 = hw.array_get %4[%sel] : !hw.array<4xi1>, i2
|
|
// CHECK-NEXT: hw.output %5 : i1
|
|
}
|
|
|
|
// CHECK-LABEL: @Wires
|
|
hw.module @Wires(in %a: i42) {
|
|
// Trivial wires should fold to their input.
|
|
%0 = hw.wire %a : i42
|
|
%1 = hw.wire %a {sv.namehint = "foo"} : i42
|
|
hw.instance "fold1" @WiresKeep(keep: %0: i42) ->()
|
|
hw.instance "fold2" @WiresKeep(keep: %1: i42) -> ()
|
|
// CHECK-NOT: hw.wire
|
|
// CHECK-NEXT: hw.instance "fold1" @WiresKeep(keep: %a: i42)
|
|
// CHECK-NEXT: hw.instance "fold2" @WiresKeep(keep: %a: i42)
|
|
|
|
// Wires shouldn't fold if they have a symbol or other attributes.
|
|
hw.wire %a sym @someSym : i42
|
|
hw.wire %a {someAttr} : i42
|
|
// CHECK-NEXT: hw.wire %a sym @someSym
|
|
// CHECK-NEXT: hw.wire %a {someAttr}
|
|
|
|
// Wires should push their name or name hint onto their input when folding.
|
|
%2 = comb.mul %a, %a : i42
|
|
%3 = comb.mul %a, %a : i42
|
|
%4 = comb.mul %a, %a {sv.namehint = "preserve"} : i42
|
|
%5 = comb.mul %a, %a : i42
|
|
%someName1 = hw.wire %2 : i42
|
|
%6 = hw.wire %3 {sv.namehint = "someName2"} : i42
|
|
%7 = hw.wire %4 {sv.namehint = "_ignored"} : i42
|
|
%someName3 = hw.wire %5 {sv.namehint = "someName3"} : i42
|
|
hw.instance "names1" @WiresKeep(keep: %someName1: i42) -> ()
|
|
hw.instance "names2" @WiresKeep(keep: %6: i42) -> ()
|
|
hw.instance "names3" @WiresKeep(keep: %7: i42) -> ()
|
|
hw.instance "names4" @WiresKeep(keep: %someName3: i42) -> ()
|
|
// CHECK-NEXT: %2 = comb.mul %a, %a {sv.namehint = "someName1"}
|
|
// CHECK-NEXT: %3 = comb.mul %a, %a {sv.namehint = "someName2"}
|
|
// CHECK-NEXT: %4 = comb.mul %a, %a {sv.namehint = "preserve"}
|
|
// CHECK-NEXT: %5 = comb.mul %a, %a {sv.namehint = "someName3"}
|
|
// CHECK-NEXT: hw.instance "names1" @WiresKeep(keep: %2: i42)
|
|
// CHECK-NEXT: hw.instance "names2" @WiresKeep(keep: %3: i42)
|
|
// CHECK-NEXT: hw.instance "names3" @WiresKeep(keep: %4: i42)
|
|
// CHECK-NEXT: hw.instance "names4" @WiresKeep(keep: %5: i42)
|
|
}
|
|
hw.module.extern @WiresKeep(in %keep: i42)
|