-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CIR] Add support for float16 and bfloat
This patch adds two new CIR floating-point types, namely `!cir.f16` and `!cir.bf16`, to represent the float16 format and bfloat format, respectively. CIRGen, LLVMIR lowering, and MLIR lowering for the two new types are also included in this patch. This patch converts the clang extension type `_Float16` to `!cir.f16`, and converts the clang extension type `__bf16` type to `!cir.bf16`. The type conversion for clang extension type `__fp16` is not included in this patch since it requires additional work during CIRGen.
- Loading branch information
Showing
11 changed files
with
438 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir | ||
// RUN: FileCheck --input-file=%t.cir %s | ||
|
||
__bf16 add1(__bf16 a, __bf16 b) { | ||
return a + b; | ||
} | ||
|
||
// CHECK: cir.func @add1(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A]], %[[#B]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 add2(__bf16 a, __bf16 b, __bf16 c) { | ||
return a + b + c; | ||
} | ||
|
||
// CHECK: cir.func @add2(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#A_B:]] = cir.binop(add, %[[#A]], %[[#B]]) : !cir.bf16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A_B]], %[[#C]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 div(__bf16 a, __bf16 b) { | ||
return a / b; | ||
} | ||
|
||
// CHECK: cir.func @div(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(div, %[[#A]], %[[#B]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 mul(__bf16 a, __bf16 b) { | ||
return a * b; | ||
} | ||
|
||
// CHECK: cir.func @mul(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(mul, %[[#A]], %[[#B]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 add_and_mul1(__bf16 a, __bf16 b, __bf16 c, __bf16 d) { | ||
return a * b + c * d; | ||
} | ||
|
||
// CHECK: cir.func @add_and_mul1(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}}])) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#A_B:]] = cir.binop(mul, %[[#A]], %[[#B]]) : !cir.bf16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %2 : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#D:]] = cir.load %3 : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#C_D:]] = cir.binop(mul, %[[#C]], %[[#D]]) : !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A_B]], %[[#C_D]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 add_and_mul2(__bf16 a, __bf16 b, __bf16 c) { | ||
return (a - 6 * b) + c; | ||
} | ||
|
||
// CHECK: cir.func @add_and_mul2(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#SIX:]] = cir.const(#cir.int<6> : !s32i) : !s32i | ||
// CHECK-NEXT: %[[#SIX_FP:]] = cir.cast(int_to_float, %[[#SIX]] : !s32i), !cir.bf16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#SIX_B:]] = cir.binop(mul, %[[#SIX_FP]], %[[#B]]) : !cir.bf16 | ||
// CHECK-NEXT: %[[#ADD_LHS:]] = cir.binop(sub, %[[#A]], %[[#SIX_B]]) : !cir.bf16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %2 : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#ADD_LHS]], %[[#C]]) : !cir.bf16 | ||
// CHECK: } | ||
|
||
__bf16 addcompound(__bf16 a, __bf16 c) { | ||
c += a; | ||
return c; | ||
} | ||
|
||
// CHECK: cir.func @addcompound(%{{.+}}: !cir.bf16 loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#C_OLD:]] = cir.load %[[#C_PTR:]] : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#C_NEW:]] = cir.binop(add, %[[#C_OLD]], %[[#A]]) : !cir.bf16 | ||
// CHECK-NEXT: cir.store %[[#C_NEW]], %[[#C_PTR]] : !cir.bf16, !cir.ptr<!cir.bf16> | ||
// CHECK: } | ||
|
||
__bf16 mulcompound_int__bf16(int a, __bf16 c) { | ||
a *= c; | ||
return c; | ||
} | ||
|
||
// CHECK: cir.func @mulcompound_int__bf16(%{{.+}}: !s32i loc({{.+}}), %{{.+}}: !cir.bf16 loc({{.+}})) -> !cir.bf16 | ||
// CHECK: %[[#C:]] = cir.load %{{.+}} : !cir.ptr<!cir.bf16>, !cir.bf16 | ||
// CHECK-NEXT: %[[#A_OLD:]] = cir.load %[[#A_PTR:]] : !cir.ptr<!s32i>, !s32i | ||
// CHECK-NEXT: %[[#A_FP:]] = cir.cast(int_to_float, %[[#A_OLD]] : !s32i), !cir.bf16 | ||
// CHECK-NEXT: %[[#A_NEW_FP:]] = cir.binop(mul, %[[#A_FP]], %[[#C]]) : !cir.bf16 | ||
// CHECK-NEXT: %[[#A_NEW:]] = cir.cast(float_to_int, %[[#A_NEW_FP]] : !cir.bf16), !s32i | ||
// CHECK-NEXT: cir.store %[[#A_NEW]], %[[#A_PTR]] : !s32i, !cir.ptr<!s32i> | ||
// CHECK: } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir | ||
// RUN: FileCheck --input-file=%t.cir %s | ||
|
||
_Float16 add1(_Float16 a, _Float16 b) { | ||
return a + b; | ||
} | ||
|
||
// CHECK: cir.func @add1(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A]], %[[#B]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 add2(_Float16 a, _Float16 b, _Float16 c) { | ||
return a + b + c; | ||
} | ||
|
||
// CHECK: cir.func @add2(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#A_B:]] = cir.binop(add, %[[#A]], %[[#B]]) : !cir.f16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A_B]], %[[#C]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 div(_Float16 a, _Float16 b) { | ||
return a / b; | ||
} | ||
|
||
// CHECK: cir.func @div(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(div, %[[#A]], %[[#B]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 mul(_Float16 a, _Float16 b) { | ||
return a * b; | ||
} | ||
|
||
// CHECK: cir.func @mul(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(mul, %[[#A]], %[[#B]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 add_and_mul1(_Float16 a, _Float16 b, _Float16 c, _Float16 d) { | ||
return a * b + c * d; | ||
} | ||
|
||
// CHECK: cir.func @add_and_mul1(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}}])) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#A_B:]] = cir.binop(mul, %[[#A]], %[[#B]]) : !cir.f16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %2 : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#D:]] = cir.load %3 : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#C_D:]] = cir.binop(mul, %[[#C]], %[[#D]]) : !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#A_B]], %[[#C_D]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 add_and_mul2(_Float16 a, _Float16 b, _Float16 c) { | ||
return (a - 6 * b) + c; | ||
} | ||
|
||
// CHECK: cir.func @add_and_mul2(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#SIX:]] = cir.const(#cir.int<6> : !s32i) : !s32i | ||
// CHECK-NEXT: %[[#SIX_FP:]] = cir.cast(int_to_float, %[[#SIX]] : !s32i), !cir.f16 | ||
// CHECK-NEXT: %[[#B:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#SIX_B:]] = cir.binop(mul, %[[#SIX_FP]], %[[#B]]) : !cir.f16 | ||
// CHECK-NEXT: %[[#ADD_LHS:]] = cir.binop(sub, %[[#A]], %[[#SIX_B]]) : !cir.f16 | ||
// CHECK-NEXT: %[[#C:]] = cir.load %2 : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#ADD_LHS]], %[[#C]]) : !cir.f16 | ||
// CHECK: } | ||
|
||
_Float16 addcompound(_Float16 a, _Float16 c) { | ||
c += a; | ||
return c; | ||
} | ||
|
||
// CHECK: cir.func @addcompound(%{{.+}}: !cir.f16 loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#A:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#C_OLD:]] = cir.load %[[#C_PTR:]] : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#C_NEW:]] = cir.binop(add, %[[#C_OLD]], %[[#A]]) : !cir.f16 | ||
// CHECK-NEXT: cir.store %[[#C_NEW]], %[[#C_PTR]] : !cir.f16, !cir.ptr<!cir.f16> | ||
// CHECK: } | ||
|
||
_Float16 mulcompound_int_float16(int a, _Float16 c) { | ||
a *= c; | ||
return c; | ||
} | ||
|
||
// CHECK: cir.func @mulcompound_int_float16(%{{.+}}: !s32i loc({{.+}}), %{{.+}}: !cir.f16 loc({{.+}})) -> !cir.f16 | ||
// CHECK: %[[#C:]] = cir.load %{{.+}} : !cir.ptr<!cir.f16>, !cir.f16 | ||
// CHECK-NEXT: %[[#A_OLD:]] = cir.load %[[#A_PTR:]] : !cir.ptr<!s32i>, !s32i | ||
// CHECK-NEXT: %[[#A_FP:]] = cir.cast(int_to_float, %[[#A_OLD]] : !s32i), !cir.f16 | ||
// CHECK-NEXT: %[[#A_NEW_FP:]] = cir.binop(mul, %[[#A_FP]], %[[#C]]) : !cir.f16 | ||
// CHECK-NEXT: %[[#A_NEW:]] = cir.cast(float_to_int, %[[#A_NEW_FP]] : !cir.f16), !s32i | ||
// CHECK-NEXT: cir.store %[[#A_NEW]], %[[#A_PTR]] : !s32i, !cir.ptr<!s32i> | ||
// CHECK: } |
Oops, something went wrong.