From a6cef539be94e7c76735c50adf0f3d179fb01c3b Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 9 Jun 2025 16:29:19 +0100 Subject: [PATCH 1/3] [GlobalOpt] Bail out for ConstantPtrAuth in isSimpleEnoughtToCommit. Bail out for ConstantPtrAuth constants in isSimpleEnoughValueToCommitHelper to prevent crash in cast below. --- llvm/lib/Transforms/Utils/Evaluator.cpp | 3 +++ .../global-constructor-ptrauth-constant.ll | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index 2af447aadce22..ecdcdf55d5089 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -74,6 +74,9 @@ isSimpleEnoughValueToCommitHelper(Constant *C, return true; } + if (isa(C)) + return false; + // We don't know exactly what relocations are allowed in constant expressions, // so we allow &global+constantoffset, which is safe and uniformly supported // across targets. diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll new file mode 100644 index 0000000000000..ef64b3eb1147c --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5 +; RUN: opt -p globalopt -S %s | FileCheck %s + +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }] + +@foo = internal global ptr null + +declare void @user(ptr) + +;. +; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }] +; CHECK: @foo = internal global ptr null +;. +define void @ctor() { +; CHECK-LABEL: define void @ctor() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr ptrauth (ptr @foo, i32 0), ptr [[DST]], align 8 +; CHECK-NEXT: call void @user(ptr [[DST]]) +; CHECK-NEXT: ret void +; +entry: + %dst = alloca ptr, align 8 + store ptr ptrauth (ptr @foo, i32 0), ptr %dst, align 8 + call void @user(ptr %dst) + ret void +} From 8a97ffe148eddcbcabfe698b101628d44484c91c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Tue, 10 Jun 2025 09:11:02 +0100 Subject: [PATCH 2/3] !fixup use dyn_cast --- llvm/lib/Transforms/Utils/Evaluator.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index ecdcdf55d5089..d1db2ee29f3a2 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -74,13 +74,12 @@ isSimpleEnoughValueToCommitHelper(Constant *C, return true; } - if (isa(C)) - return false; - // We don't know exactly what relocations are allowed in constant expressions, // so we allow &global+constantoffset, which is safe and uniformly supported // across targets. - ConstantExpr *CE = cast(C); + ConstantExpr *CE = dyn_cast(C); + if (!CE) + return false; switch (CE->getOpcode()) { case Instruction::BitCast: // Bitcast is fine if the casted value is fine. From bfd7b01f7545835673d5cf71e5efd49a66a5f537 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Wed, 11 Jun 2025 20:35:40 +0100 Subject: [PATCH 3/3] !fixup add tests with nocfi, dso_local_equivalent constsnts. --- .../global-constructor-complex-constants.ll | 64 +++++++++++++++++++ .../global-constructor-ptrauth-constant.ll | 27 -------- 2 files changed, 64 insertions(+), 27 deletions(-) create mode 100644 llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll delete mode 100644 llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll new file mode 100644 index 0000000000000..6d9bdc41a0041 --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll @@ -0,0 +1,64 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5 +; RUN: opt -p globalopt -S %s | FileCheck %s + +@llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor_nocfi, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor_dso_local_equivalent, ptr null }] + +@foo = internal global ptr null + +declare void @user(ptr) + +;. +; CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor_nocfi, ptr null }, { i32, ptr, ptr } { i32 65535, ptr @ctor_dso_local_equivalent, ptr null }] +; CHECK: @foo = internal global ptr null +;. +define void @ctor() { +; CHECK-LABEL: define void @ctor() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr ptrauth (ptr @foo, i32 0), ptr [[DST]], align 8 +; CHECK-NEXT: call void @user(ptr [[DST]]) +; CHECK-NEXT: ret void +; +entry: + %dst = alloca ptr, align 8 + store ptr ptrauth (ptr @foo, i32 0), ptr %dst, align 8 + call void @user(ptr %dst) + ret void +} + +define void @ctor_nocfi() { +; CHECK-LABEL: define void @ctor_nocfi() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr no_cfi @foo, ptr [[DST]], align 8 +; CHECK-NEXT: call void @user(ptr [[DST]]) +; CHECK-NEXT: ret void +; +entry: + %dst = alloca ptr, align 8 + store ptr no_cfi @foo, ptr %dst, align 8 + call void @user(ptr %dst) + ret void +} + +define void @fn() { +; CHECK-LABEL: define void @fn() { +; CHECK-NEXT: ret void +; + ret void +} + +define void @ctor_dso_local_equivalent() { +; CHECK-LABEL: define void @ctor_dso_local_equivalent() { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 +; CHECK-NEXT: store ptr dso_local_equivalent @fn, ptr [[DST]], align 8 +; CHECK-NEXT: call void @user(ptr [[DST]]) +; CHECK-NEXT: ret void +; +entry: + %dst = alloca ptr, align 8 + store ptr dso_local_equivalent @fn, ptr %dst, align 8 + call void @user(ptr %dst) + ret void +} diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll deleted file mode 100644 index ef64b3eb1147c..0000000000000 --- a/llvm/test/Transforms/GlobalOpt/global-constructor-ptrauth-constant.ll +++ /dev/null @@ -1,27 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5 -; RUN: opt -p globalopt -S %s | FileCheck %s - -@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }] - -@foo = internal global ptr null - -declare void @user(ptr) - -;. -; CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @ctor, ptr null }] -; CHECK: @foo = internal global ptr null -;. -define void @ctor() { -; CHECK-LABEL: define void @ctor() { -; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 -; CHECK-NEXT: store ptr ptrauth (ptr @foo, i32 0), ptr [[DST]], align 8 -; CHECK-NEXT: call void @user(ptr [[DST]]) -; CHECK-NEXT: ret void -; -entry: - %dst = alloca ptr, align 8 - store ptr ptrauth (ptr @foo, i32 0), ptr %dst, align 8 - call void @user(ptr %dst) - ret void -}