[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