[llvm] f32f048 - [llvm] Use ABI instead of preferred alignment for const prop checks (#142500)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 4 10:58:03 PDT 2025
Author: PiJoules
Date: 2025-06-04T10:57:59-07:00
New Revision: f32f048719455b4813ff7115e4f3a6cdc65efff0
URL: https://github.com/llvm/llvm-project/commit/f32f048719455b4813ff7115e4f3a6cdc65efff0
DIFF: https://github.com/llvm/llvm-project/commit/f32f048719455b4813ff7115e4f3a6cdc65efff0.diff
LOG: [llvm] Use ABI instead of preferred alignment for const prop checks (#142500)
We'd hit an assertion checking proper alignment for an i8 when building
chromium because we used the prefered alignment (which is 4 bytes)
instead of the ABI alignment (which is 1 byte). The ABI alignment should
be used because that's the actual alignment needed to load a constant
from the vtable.
This also updates the two `virtual-const-prop-small-alignment-*` to
explicitly give ABI alignments for i64s.
Added:
llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-ignore-preferred-alignment.ll
Modified:
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-32.ll
llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-64.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index 3a25255d0a4c8..a7d9f3ba24b24 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -1845,7 +1845,7 @@ bool DevirtModule::tryVirtualConstProp(
if (BitWidth > 64)
return false;
- Align TypeAlignment = M.getDataLayout().getPrefTypeAlign(RetType);
+ Align TypeAlignment = M.getDataLayout().getABIIntegerTypeAlignment(BitWidth);
// Make sure that each function is defined, does not access memory, takes at
// least one argument, does not use its first argument (which we assume is
diff --git a/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-ignore-preferred-alignment.ll b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-ignore-preferred-alignment.ll
new file mode 100644
index 0000000000000..6bee92301e330
--- /dev/null
+++ b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-ignore-preferred-alignment.ll
@@ -0,0 +1,110 @@
+;; Demonstrate that the ABI alignment is used over the preferred alignment.
+;;
+;; In both runs, pointers are 32-bit but we can only store the function returing
+;; the 64-bit constant in the vtable if the ABI alignment for an i64 is 32 since
+;; we cannot guarantee a 64-bit ABI alignment if the vtable is 32-bit aligned.
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:32:32-i64:32:64" %s | FileCheck %s --check-prefixes=COMMON,ABI32
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:32:32-i64:64:64" %s | FileCheck %s --check-prefixes=COMMON,ABI64
+
+; ABI32: [[VT6DATA:@[^ ]*]] = {{.*}} { [4 x i8], [2 x ptr], [8 x i8] }
+; ABI32-SAME: [8 x i8] c"\05\00\00\00\00\00\00\00"
+; ABI64: [[VT6DATA:@[^ ]*]] = {{.*}} { [4 x i8], [2 x ptr], [0 x i8] }
+; ABI64-SAME: zeroinitializer
+; COMMON-SAME: }, !type [[T:![0-9]+]]
+ at vt6 = constant [2 x ptr] [
+ptr @vf10i8,
+ptr @vf5i64
+], !type !1
+
+; ABI32: [[VT6DATA:@[^ ]*]] = {{.*}} { [4 x i8], [2 x ptr], [8 x i8] }
+; ABI32-SAME: [8 x i8] c"\06\00\00\00\00\00\00\00"
+; ABI64: [[VT6DATA:@[^ ]*]] = {{.*}} { [4 x i8], [2 x ptr], [0 x i8] }
+; ABI64-SAME: zeroinitializer
+; COMMON-SAME: }, !type [[T]]
+ at vt7 = constant [2 x ptr] [
+ptr @vf9i8,
+ptr @vf6i64
+], !type !1
+
+define i1 @vf0i1(ptr %this) readnone {
+ ret i1 0
+}
+
+define i1 @vf1i1(ptr %this) readnone {
+ ret i1 1
+}
+
+define i8 @vf0i8(ptr %this) readnone {
+ ret i8 2
+}
+
+define i8 @vf1i8(ptr %this) readnone {
+ ret i8 3
+}
+
+define i32 @vf1i32(ptr %this) readnone {
+ ret i32 1
+}
+
+define i32 @vf2i32(ptr %this) readnone {
+ ret i32 2
+}
+
+define i32 @vf3i32(ptr %this) readnone {
+ ret i32 3
+}
+
+define i32 @vf4i32(ptr %this) readnone {
+ ret i32 4
+}
+
+define i64 @vf5i64(ptr %this) readnone {
+ ret i64 5
+}
+
+define i64 @vf6i64(ptr %this) readnone {
+ ret i64 6
+}
+
+define i8 @vf9i8(ptr %this) readnone {
+ ret i8 10
+}
+
+define i8 @vf10i8(ptr %this) readnone {
+ ret i8 11
+}
+
+; COMMON-LABEL: define i8 @call0(
+define i8 @call0(ptr %obj) {
+ %vtable = load ptr, ptr %obj
+ %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
+ call void @llvm.assume(i1 %p)
+ %fptrptr = getelementptr [3 x ptr], ptr %vtable, i32 0, i32 0
+ %fptr = load ptr, ptr %fptrptr
+ %result = call i8 %fptr(ptr %obj)
+ ret i8 %result
+ ; COMMON: [[VTGEP:%[^ ]*]] = getelementptr i8, ptr %vtable, i32 -1
+ ; COMMON: [[VTLOAD:%[^ ]*]] = load i8, ptr [[VTGEP]]
+ ; COMMON: ret i8 [[VTLOAD]]
+}
+
+; COMMON-LABEL: define i64 @call1(
+define i64 @call1(ptr %obj) {
+ %vtable = load ptr, ptr %obj
+ %p = call i1 @llvm.type.test(ptr %vtable, metadata !"typeid")
+ call void @llvm.assume(i1 %p)
+ %fptrptr = getelementptr [3 x ptr], ptr %vtable, i32 0, i32 1
+ %fptr = load ptr, ptr %fptrptr
+ %result = call i64 %fptr(ptr %obj)
+ ret i64 %result
+ ; ABI32: [[VTGEP:%[^ ]*]] = getelementptr i8, ptr %vtable, i32 8
+ ; ABI32-NEXT: [[VTLOAD:%[^ ]*]] = load i64, ptr [[VTGEP]]
+ ; ABI64: [[VTGEP:%[^ ]*]] = getelementptr [3 x ptr], ptr %vtable, i32 0, i32 1
+ ; ABI64-NEXT: [[FUNC:%[^ ]*]] = load ptr, ptr [[VTGEP]], align 4
+ ; ABI64-NEXT: [[VTLOAD:%[^ ]*]] = call i64 [[FUNC]](ptr %obj)
+ ; COMMON-NEXT: ret i64 [[VTLOAD]]
+}
+
+; COMMON: [[T]] = !{i32 4, !"typeid"}
+
+!1 = !{i32 0, !"typeid"}
diff --git a/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-32.ll b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-32.ll
index ab76f2c22e343..314b1ee13a800 100644
--- a/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-32.ll
+++ b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-32.ll
@@ -1,7 +1,9 @@
-; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s | FileCheck %s
-
;; This target uses 32-bit sized and aligned pointers.
-target datalayout = "e-p:32:32"
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:32:32-i64:64:64" %s | FileCheck %s
+
+;; The tests should be the exact same even with
diff erent preferred alignments since
+;; the ABI alignment is used.
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:32:32-i64:64:128" %s | FileCheck %s
;; Constant propagation should be agnostic towards sections.
;; Also the new global should be in the original vtable's section.
diff --git a/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-64.ll b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-64.ll
index c83fbc6ed5a19..9f39b65e26650 100644
--- a/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-64.ll
+++ b/llvm/test/Transforms/WholeProgramDevirt/virtual-const-prop-small-alignment-64.ll
@@ -1,7 +1,9 @@
-; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility %s | FileCheck %s
-
;; This target uses 64-bit sized and aligned pointers.
-target datalayout = "e-p:64:64"
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:64:64-i64:64:64" %s | FileCheck %s
+
+;; The tests should be the exact same even with
diff erent preferred alignments since
+;; the ABI alignment is used.
+; RUN: opt -S -passes=wholeprogramdevirt -whole-program-visibility --data-layout="e-p:64:64-i64:64:128" %s | FileCheck %s
;; Constant propagation should be agnostic towards sections.
;; Also the new global should be in the original vtable's section.
More information about the llvm-commits
mailing list