[clang] cb3174b - [clang][CodeGen] fix UB in aarch64 bfloat16 scalar conversion (#89062)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 29 05:18:41 PDT 2024


Author: nihui
Date: 2024-04-29T13:18:37+01:00
New Revision: cb3174bd7895535d2f397695b5b20b1e90876997

URL: https://github.com/llvm/llvm-project/commit/cb3174bd7895535d2f397695b5b20b1e90876997
DIFF: https://github.com/llvm/llvm-project/commit/cb3174bd7895535d2f397695b5b20b1e90876997.diff

LOG: [clang][CodeGen] fix UB in aarch64 bfloat16 scalar conversion (#89062)

do not bitcast 16bit `bfloat16` to 32bit `int32_t` directly
bitcast to `int16_t`, and then upcast to `int32_t`

Fix ASAN runtime error when calling vcvtah_f32_bf16
`==21842==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x007fda1dd063 at pc 0x005c0361c234 bp 0x007fda1dd030 sp 0x007fda1dd028
`

without patch
```c
__ai __attribute__((target("bf16"))) float32_t vcvtah_f32_bf16(bfloat16_t __p0) {
  float32_t __ret;
bfloat16_t __reint = __p0;
int32_t __reint1 = *(int32_t *) &__reint << 16;
  __ret = *(float32_t *) &__reint1;
  return __ret;
}
```

with this patch
```c
__ai __attribute__((target("bf16"))) float32_t vcvtah_f32_bf16(bfloat16_t __p0) {
  float32_t __ret;
bfloat16_t __reint = __p0;
int32_t __reint1 = (int32_t)(*(int16_t *) &__reint) << 16;
  __ret = *(float32_t *) &__reint1;
  return __ret;
}
```

fix issue https://github.com/llvm/llvm-project/issues/61983

Added: 
    

Modified: 
    clang/include/clang/Basic/arm_neon.td
    clang/test/CodeGen/arm-bf16-convert-intrinsics.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td
index 6d655c39360d3b..6390ba3f9fe5e5 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -275,7 +275,7 @@ def OP_VCVT_BF16_F32_HI_A32
                            (call "vget_low", $p0))>;
 
 def OP_CVT_F32_BF16
-    : Op<(bitcast "R", (op "<<", (bitcast "int32_t", $p0),
+    : Op<(bitcast "R", (op "<<", (cast "int32_t", (bitcast "int16_t", $p0)),
                                  (literal "int32_t", "16")))>;
 
 //===----------------------------------------------------------------------===//

diff  --git a/clang/test/CodeGen/arm-bf16-convert-intrinsics.c b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
index f50eaf371028cd..0f2c5b2546fa35 100644
--- a/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
+++ b/clang/test/CodeGen/arm-bf16-convert-intrinsics.c
@@ -426,11 +426,12 @@ bfloat16_t test_vcvth_bf16_f32(float32_t a) {
 // CHECK-NEXT:    [[__REINT_I:%.*]] = alloca bfloat, align 2
 // CHECK-NEXT:    [[__REINT1_I:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store bfloat [[A:%.*]], ptr [[__REINT_I]], align 2
-// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[__REINT_I]], align 2
-// CHECK-NEXT:    [[SHL_I:%.*]] = shl i32 [[TMP1]], 16
+// CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[__REINT_I]], align 2
+// CHECK-NEXT:    [[CONV_I:%.*]] = sext i16 [[TMP0]] to i32
+// CHECK-NEXT:    [[SHL_I:%.*]] = shl i32 [[CONV_I]], 16
 // CHECK-NEXT:    store i32 [[SHL_I]], ptr [[__REINT1_I]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load float, ptr [[__REINT1_I]], align 4
-// CHECK-NEXT:    ret float [[TMP3]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load float, ptr [[__REINT1_I]], align 4
+// CHECK-NEXT:    ret float [[TMP1]]
 //
 float32_t test_vcvtah_f32_bf16(bfloat16_t a) {
   return vcvtah_f32_bf16(a);


        


More information about the cfe-commits mailing list