https://github.com/bwendling created 
https://github.com/llvm/llvm-project/pull/110487

We were missing a load of the value after emitting the MemberExpr. This was 
causing __builtin_dynamic_object_size to return 0 incorrectly.

>From 375a71d114fffb94c16455f476364a7de9e08191 Mon Sep 17 00:00:00 2001
From: Bill Wendling <mo...@google.com>
Date: Mon, 30 Sep 2024 03:41:15 -0700
Subject: [PATCH] [Clang][CodeGen] Emit load of value

We were missing a load of the value after emitting the MemberExpr. This
was causing __builtin_dynamic_object_size to return 0 incorrectly.

Signed-off-by: Bill Wendling <mo...@google.com>
---
 clang/lib/CodeGen/CGExpr.cpp                  |  1 +
 clang/test/CodeGen/attr-counted-by-pr110385.c | 74 +++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 clang/test/CodeGen/attr-counted-by-pr110385.c

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index df4994ba9af6e1..4e26e9f7076777 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1169,6 +1169,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField(
     LValue LV = EmitMemberExpr(ME);
     Address Addr = LV.getAddress();
     Res = Addr.emitRawPointer(*this);
+    Res = Builder.CreateAlignedLoad(Res->getType(), Res, getPointerAlign());
   } else if (StructBase->getType()->isPointerType()) {
     LValueBaseInfo BaseInfo;
     TBAAAccessInfo TBAAInfo;
diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c 
b/clang/test/CodeGen/attr-counted-by-pr110385.c
new file mode 100644
index 00000000000000..1f11bc1a04c81b
--- /dev/null
+++ b/clang/test/CodeGen/attr-counted-by-pr110385.c
@@ -0,0 +1,74 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 4
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fstrict-flex-arrays=2 
-emit-llvm -o - %s | FileCheck %s
+
+struct bch_val {
+  unsigned long int __nothing[0];
+};
+
+struct bch_xattr {
+  struct bch_val v;
+  unsigned char x_type;
+  unsigned char x_name_len;
+  unsigned char x_name[] __attribute__((__counted_by__(x_name_len)));
+};
+
+struct bkey_s_c {
+  const struct bch_val *v;
+};
+
+struct bkey_s_c_xattr {
+  union {
+    const struct bch_xattr *v;
+    struct bkey_s_c s_c;
+  };
+};
+
+// CHECK-LABEL: define dso_local i64 @test1(
+// CHECK-SAME: ptr [[K_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[K:%.*]] = alloca [[STRUCT_BKEY_S_C:%.*]], align 8
+// CHECK-NEXT:    [[XATTR:%.*]] = alloca [[STRUCT_BKEY_S_C_XATTR:%.*]], align 8
+// CHECK-NEXT:    [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw 
[[STRUCT_BKEY_S_C]], ptr [[K]], i32 0, i32 0
+// CHECK-NEXT:    store ptr [[K_COERCE]], ptr [[COERCE_DIVE]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw 
[[STRUCT_BKEY_S_C_XATTR]], ptr [[XATTR]], i32 0, i32 0
+// CHECK-NEXT:    [[V:%.*]] = getelementptr inbounds nuw [[STRUCT_BKEY_S_C]], 
ptr [[K]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[V]], align 8
+// CHECK-NEXT:    [[ADD_PTR:%.*]] = getelementptr inbounds 
[[STRUCT_BCH_VAL:%.*]], ptr [[TMP1]], i64 0
+// CHECK-NEXT:    store ptr [[ADD_PTR]], ptr [[TMP0]], align 8
+// CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw 
[[STRUCT_BKEY_S_C_XATTR]], ptr [[XATTR]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[TMP2]], align 8
+// CHECK-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds 
[[STRUCT_BCH_XATTR:%.*]], ptr [[TMP3]], i32 0, i32 2
+// CHECK-NEXT:    [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr 
[[DOT_COUNTED_BY_GEP]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64
+// CHECK-NEXT:    [[TMP5:%.*]] = mul nuw i64 [[TMP4]], 1
+// CHECK-NEXT:    [[TMP6:%.*]] = icmp sgt i64 [[TMP4]], -1
+// CHECK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP5]], i64 0
+// CHECK-NEXT:    ret i64 [[TMP7]]
+//
+unsigned long int test1(struct bkey_s_c k) {
+  struct bkey_s_c_xattr xattr = (struct bkey_s_c_xattr){
+      .v = (struct bch_xattr *)(k.v - __builtin_offsetof(struct bch_xattr, v))
+  };
+
+  return __builtin_dynamic_object_size(xattr.v->x_name, 0);
+}
+
+// CHECK-LABEL: define dso_local i64 @test2(
+// CHECK-SAME: ptr noundef [[XATTR:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[XATTR_ADDR:%.*]] = alloca ptr, align 8
+// CHECK-NEXT:    store ptr [[XATTR]], ptr [[XATTR_ADDR]], align 8
+// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[XATTR_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw 
[[STRUCT_BKEY_S_C_XATTR:%.*]], ptr [[TMP0]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8
+// CHECK-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds 
[[STRUCT_BCH_XATTR:%.*]], ptr [[TMP2]], i32 0, i32 2
+// CHECK-NEXT:    [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr 
[[DOT_COUNTED_BY_GEP]], align 4
+// CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64
+// CHECK-NEXT:    [[TMP4:%.*]] = mul nuw i64 [[TMP3]], 1
+// CHECK-NEXT:    [[TMP5:%.*]] = icmp sgt i64 [[TMP3]], -1
+// CHECK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP5]], i64 [[TMP4]], i64 0
+// CHECK-NEXT:    ret i64 [[TMP6]]
+//
+unsigned long int test2(struct bkey_s_c_xattr *xattr) {
+  return __builtin_dynamic_object_size(xattr->v->x_name, 0);
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to