From 64a4bacdfd817eaba8691a3bb55be6bc52da377b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jun 2025 12:51:38 +0200 Subject: [PATCH 1/2] [ConstantFolding] Bail out when reading padding of type ReadDataFromGlobal() did not handle reads from the padding of types (in the sense of type store size != type alloc size, rather than struct padding). Just bail out in that case. (Alternatively could make this return zero as well, but the value seems dubious.) Fixes https://github.com/llvm/llvm-project/issues/144279. --- llvm/lib/Analysis/ConstantFolding.cpp | 4 ++ .../InstSimplify/ConstProp/loads.ll | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 2b7a438a9ef01..7bd67d2a95dbc 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -432,6 +432,10 @@ bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr, assert(ByteOffset <= DL.getTypeAllocSize(C->getType()) && "Out of range access"); + // Trying to read type padding. + if (ByteOffset >= DL.getTypeStoreSize(C->getType())) + return false; + // If this element is zero or undefined, we can just return since *CurPtr is // zero initialized. if (isa(C) || isa(C)) diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll index dd75560e25ced..134025514dcf6 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll @@ -441,3 +441,41 @@ define i128 @load-128bit(){ %1 = load i128, ptr @global128, align 4 ret i128 %1 } + + +@i40_struct = constant { i40, i8 } { i40 0, i8 1 } +@i40_array = constant [2 x i40] [i40 0, i40 1] + +define i8 @load_i40_struct_padding() { +; CHECK-LABEL: @load_i40_struct_padding( +; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6), align 1 +; CHECK-NEXT: ret i8 [[V]] +; + %v = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6) + ret i8 %v +} + +define i16 @load_i40_struct_partial_padding() { +; CHECK-LABEL: @load_i40_struct_partial_padding( +; CHECK-NEXT: ret i16 0 +; + %v = load i16, ptr getelementptr (i8, ptr @i40_struct, i64 4) + ret i16 %v +} + +define i8 @load_i40_array_padding() { +; CHECK-LABEL: @load_i40_array_padding( +; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6), align 1 +; CHECK-NEXT: ret i8 [[V]] +; + %v = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6) + ret i8 %v +} + +define i16 @load_i40_array_partial_padding() { +; CHECK-LABEL: @load_i40_array_partial_padding( +; CHECK-NEXT: ret i16 0 +; + %v = load i16, ptr getelementptr (i8, ptr @i40_array, i64 4) + ret i16 %v +} From 78692f2a549a6f68a892e3c19e59b1ffc4ad3edc Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jun 2025 16:48:56 +0200 Subject: [PATCH 2/2] Return zero instead --- llvm/lib/Analysis/ConstantFolding.cpp | 4 ++-- llvm/test/Transforms/InstSimplify/ConstProp/loads.ll | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 7bd67d2a95dbc..b58f9b26a8651 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -432,9 +432,9 @@ bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr, assert(ByteOffset <= DL.getTypeAllocSize(C->getType()) && "Out of range access"); - // Trying to read type padding. + // Reading type padding, return zero. if (ByteOffset >= DL.getTypeStoreSize(C->getType())) - return false; + return true; // If this element is zero or undefined, we can just return since *CurPtr is // zero initialized. diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll index 134025514dcf6..061c6834eb97d 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll @@ -448,8 +448,7 @@ define i128 @load-128bit(){ define i8 @load_i40_struct_padding() { ; CHECK-LABEL: @load_i40_struct_padding( -; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6), align 1 -; CHECK-NEXT: ret i8 [[V]] +; CHECK-NEXT: ret i8 0 ; %v = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6) ret i8 %v @@ -465,8 +464,7 @@ define i16 @load_i40_struct_partial_padding() { define i8 @load_i40_array_padding() { ; CHECK-LABEL: @load_i40_array_padding( -; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6), align 1 -; CHECK-NEXT: ret i8 [[V]] +; CHECK-NEXT: ret i8 0 ; %v = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6) ret i8 %v