mirror of
https://src.fedoraproject.org/rpms/llvm.git
synced 2024-11-24 17:34:47 +00:00
Backport fix for rhbz#2275090
This commit is contained in:
parent
5a86502fba
commit
ece9c09ef1
2 changed files with 303 additions and 1 deletions
295
0001-PPCMergeStringPool-Avoid-replacing-constant-with-ins.patch
Normal file
295
0001-PPCMergeStringPool-Avoid-replacing-constant-with-ins.patch
Normal file
|
@ -0,0 +1,295 @@
|
|||
From 1184a9cb30e6a12c883b918867f2f06bc3096fc0 Mon Sep 17 00:00:00 2001
|
||||
From: Nikita Popov <npopov@redhat.com>
|
||||
Date: Thu, 9 May 2024 13:27:20 +0900
|
||||
Subject: [PATCH] [PPCMergeStringPool] Avoid replacing constant with
|
||||
instruction (#88846)
|
||||
|
||||
String pool merging currently, for a reason that's not entirely clear to
|
||||
me, tries to create GEP instructions instead of GEP constant expressions
|
||||
when replacing constant references. It only uses constant expressions in
|
||||
cases where this is required. However, it does not catch all cases where
|
||||
such a requirement exists. For example, the landingpad catch clause has
|
||||
to be a constant.
|
||||
|
||||
Fix this by always using the constant expression variant, which also
|
||||
makes the implementation simpler.
|
||||
|
||||
Additionally, there are some edge cases where even replacement with a
|
||||
constant GEP is not legal. The one I am aware of is the
|
||||
llvm.eh.typeid.for intrinsic, so add a special case to forbid
|
||||
replacements for it.
|
||||
|
||||
Fixes https://github.com/llvm/llvm-project/issues/88844.
|
||||
|
||||
(cherry picked from commit 3a3aeb8eba40e981d3a9ff92175f949c2f3d4434)
|
||||
---
|
||||
.../lib/Target/PowerPC/PPCMergeStringPool.cpp | 57 ++++++-------------
|
||||
.../mergeable-string-pool-exceptions.ll | 47 +++++++++++++++
|
||||
.../PowerPC/mergeable-string-pool-large.ll | 14 ++---
|
||||
.../mergeable-string-pool-pass-only.mir | 18 +++---
|
||||
.../CodeGen/PowerPC/mergeable-string-pool.ll | 14 ++---
|
||||
5 files changed, 87 insertions(+), 63 deletions(-)
|
||||
create mode 100644 llvm/test/CodeGen/PowerPC/mergeable-string-pool-exceptions.ll
|
||||
|
||||
diff --git a/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp b/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
|
||||
index d9465e86d896..ebd876d50c44 100644
|
||||
--- a/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
|
||||
+++ b/llvm/lib/Target/PowerPC/PPCMergeStringPool.cpp
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
+#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/ValueSymbolTable.h"
|
||||
#include "llvm/Pass.h"
|
||||
@@ -116,9 +117,20 @@ private:
|
||||
// sure that they can be replaced.
|
||||
static bool hasReplaceableUsers(GlobalVariable &GV) {
|
||||
for (User *CurrentUser : GV.users()) {
|
||||
- // Instruction users are always valid.
|
||||
- if (isa<Instruction>(CurrentUser))
|
||||
+ if (auto *I = dyn_cast<Instruction>(CurrentUser)) {
|
||||
+ // Do not merge globals in exception pads.
|
||||
+ if (I->isEHPad())
|
||||
+ return false;
|
||||
+
|
||||
+ if (auto *II = dyn_cast<IntrinsicInst>(I)) {
|
||||
+ // Some intrinsics require a plain global.
|
||||
+ if (II->getIntrinsicID() == Intrinsic::eh_typeid_for)
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Other instruction users are always valid.
|
||||
continue;
|
||||
+ }
|
||||
|
||||
// We cannot replace GlobalValue users because they are not just nodes
|
||||
// in IR. To replace a user like this we would need to create a new
|
||||
@@ -302,14 +314,6 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
|
||||
Users.push_back(CurrentUser);
|
||||
|
||||
for (User *CurrentUser : Users) {
|
||||
- Instruction *UserInstruction = dyn_cast<Instruction>(CurrentUser);
|
||||
- Constant *UserConstant = dyn_cast<Constant>(CurrentUser);
|
||||
-
|
||||
- // At this point we expect that the user is either an instruction or a
|
||||
- // constant.
|
||||
- assert((UserConstant || UserInstruction) &&
|
||||
- "Expected the user to be an instruction or a constant.");
|
||||
-
|
||||
// The user was not found so it must have been replaced earlier.
|
||||
if (!userHasOperand(CurrentUser, GlobalToReplace))
|
||||
continue;
|
||||
@@ -318,38 +322,13 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
|
||||
if (isa<GlobalValue>(CurrentUser))
|
||||
continue;
|
||||
|
||||
- if (!UserInstruction) {
|
||||
- // User is a constant type.
|
||||
- Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
|
||||
- PooledStructType, GPool, Indices);
|
||||
- UserConstant->handleOperandChange(GlobalToReplace, ConstGEP);
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- if (PHINode *UserPHI = dyn_cast<PHINode>(UserInstruction)) {
|
||||
- // GEP instructions cannot be added before PHI nodes.
|
||||
- // With getInBoundsGetElementPtr we create the GEP and then replace it
|
||||
- // inline into the PHI.
|
||||
- Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
|
||||
- PooledStructType, GPool, Indices);
|
||||
- UserPHI->replaceUsesOfWith(GlobalToReplace, ConstGEP);
|
||||
- continue;
|
||||
- }
|
||||
- // The user is a valid instruction that is not a PHINode.
|
||||
- GetElementPtrInst *GEPInst =
|
||||
- GetElementPtrInst::Create(PooledStructType, GPool, Indices);
|
||||
- GEPInst->insertBefore(UserInstruction);
|
||||
-
|
||||
- LLVM_DEBUG(dbgs() << "Inserting GEP before:\n");
|
||||
- LLVM_DEBUG(UserInstruction->dump());
|
||||
-
|
||||
+ Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
|
||||
+ PooledStructType, GPool, Indices);
|
||||
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
|
||||
LLVM_DEBUG(GlobalToReplace->dump());
|
||||
LLVM_DEBUG(dbgs() << "with this:\n");
|
||||
- LLVM_DEBUG(GEPInst->dump());
|
||||
-
|
||||
- // After the GEP is inserted the GV can be replaced.
|
||||
- CurrentUser->replaceUsesOfWith(GlobalToReplace, GEPInst);
|
||||
+ LLVM_DEBUG(ConstGEP->dump());
|
||||
+ GlobalToReplace->replaceAllUsesWith(ConstGEP);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/llvm/test/CodeGen/PowerPC/mergeable-string-pool-exceptions.ll b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-exceptions.ll
|
||||
new file mode 100644
|
||||
index 000000000000..0489c74c0f81
|
||||
--- /dev/null
|
||||
+++ b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-exceptions.ll
|
||||
@@ -0,0 +1,47 @@
|
||||
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
|
||||
+; RUN: llc -mtriple=ppc64le-unknown-linux-gnu < %s | FileCheck %s
|
||||
+
|
||||
+@id = private unnamed_addr constant [4 x i8] c"@id\00", align 1
|
||||
+@id2 = private unnamed_addr constant [5 x i8] c"@id2\00", align 1
|
||||
+
|
||||
+; Higher-aligned dummy to make sure it is first in the string pool.
|
||||
+@dummy = private unnamed_addr constant [1 x i32] [i32 42], align 4
|
||||
+
|
||||
+define ptr @test1() personality ptr @__gnu_objc_personality_v0 {
|
||||
+; CHECK-LABEL: test1:
|
||||
+; CHECK: # %bb.0:
|
||||
+; CHECK-NEXT: mflr 0
|
||||
+; CHECK-NEXT: stdu 1, -32(1)
|
||||
+; CHECK-NEXT: std 0, 48(1)
|
||||
+; CHECK-NEXT: .cfi_def_cfa_offset 32
|
||||
+; CHECK-NEXT: .cfi_offset lr, 16
|
||||
+; CHECK-NEXT: addis 3, 2, .L__ModuleStringPool@toc@ha
|
||||
+; CHECK-NEXT: addi 3, 3, .L__ModuleStringPool@toc@l
|
||||
+; CHECK-NEXT: bl foo
|
||||
+; CHECK-NEXT: nop
|
||||
+ invoke void @foo(ptr @dummy)
|
||||
+ to label %cont unwind label %unwind
|
||||
+
|
||||
+cont:
|
||||
+ unreachable
|
||||
+
|
||||
+unwind:
|
||||
+ %lp = landingpad { ptr, i32 }
|
||||
+ catch ptr @id
|
||||
+ resume { ptr, i32 } %lp
|
||||
+}
|
||||
+
|
||||
+define i32 @test2() personality ptr @__gnu_objc_personality_v0 {
|
||||
+; CHECK-LABEL: test2:
|
||||
+; CHECK: # %bb.0:
|
||||
+; CHECK-NEXT: li 3, 1
|
||||
+; CHECK-NEXT: blr
|
||||
+ %id = tail call i32 @llvm.eh.typeid.for(ptr @id2)
|
||||
+ ret i32 %id
|
||||
+}
|
||||
+
|
||||
+declare i32 @__gnu_objc_personality_v0(...)
|
||||
+
|
||||
+declare i32 @llvm.eh.typeid.for(ptr)
|
||||
+
|
||||
+declare void @foo()
|
||||
diff --git a/llvm/test/CodeGen/PowerPC/mergeable-string-pool-large.ll b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-large.ll
|
||||
index b13b01b416e6..b182763ccc14 100644
|
||||
--- a/llvm/test/CodeGen/PowerPC/mergeable-string-pool-large.ll
|
||||
+++ b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-large.ll
|
||||
@@ -319,16 +319,16 @@ define dso_local signext i32 @array0() local_unnamed_addr #0 {
|
||||
; AIX32-NEXT: mflr r0
|
||||
; AIX32-NEXT: stwu r1, -96(r1)
|
||||
; AIX32-NEXT: lis r6, 0
|
||||
-; AIX32-NEXT: lwz r4, L..C0(r2) # @__ModuleStringPool
|
||||
-; AIX32-NEXT: li r5, 12
|
||||
+; AIX32-NEXT: lwz r5, L..C0(r2) # @__ModuleStringPool
|
||||
+; AIX32-NEXT: li r4, 12
|
||||
; AIX32-NEXT: addi r3, r1, 64
|
||||
; AIX32-NEXT: stw r0, 104(r1)
|
||||
; AIX32-NEXT: ori r7, r6, 35596
|
||||
-; AIX32-NEXT: rlwimi r5, r3, 0, 30, 27
|
||||
-; AIX32-NEXT: lxvw4x vs0, r4, r7
|
||||
-; AIX32-NEXT: stxvw4x vs0, 0, r5
|
||||
-; AIX32-NEXT: ori r5, r6, 35584
|
||||
-; AIX32-NEXT: lxvw4x vs0, r4, r5
|
||||
+; AIX32-NEXT: rlwimi r4, r3, 0, 30, 27
|
||||
+; AIX32-NEXT: lxvw4x vs0, r5, r7
|
||||
+; AIX32-NEXT: stxvw4x vs0, 0, r4
|
||||
+; AIX32-NEXT: ori r4, r6, 35584
|
||||
+; AIX32-NEXT: lxvw4x vs0, r5, r4
|
||||
; AIX32-NEXT: stxvw4x vs0, 0, r3
|
||||
; AIX32-NEXT: bl .calleeInt[PR]
|
||||
; AIX32-NEXT: nop
|
||||
diff --git a/llvm/test/CodeGen/PowerPC/mergeable-string-pool-pass-only.mir b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-pass-only.mir
|
||||
index e2fb0ced8f34..3d8afb604fd3 100644
|
||||
--- a/llvm/test/CodeGen/PowerPC/mergeable-string-pool-pass-only.mir
|
||||
+++ b/llvm/test/CodeGen/PowerPC/mergeable-string-pool-pass-only.mir
|
||||
@@ -35,8 +35,7 @@
|
||||
ret i32 %call
|
||||
|
||||
; CHECK-LABEL: test1
|
||||
- ; CHECK: %0 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 6
|
||||
- ; CHECK: tail call signext i32 @calleeStr
|
||||
+ ; CHECK: %call = tail call signext i32 @calleeStr(ptr noundef nonnull getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 6))
|
||||
}
|
||||
|
||||
define dso_local signext i32 @test2() local_unnamed_addr #0 {
|
||||
@@ -49,7 +48,7 @@
|
||||
ret i32 %call
|
||||
|
||||
; CHECK-LABEL: test2
|
||||
- ; CHECK: %0 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 2
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) %A, ptr noundef nonnull align 4 dereferenceable(24) getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 2), i64 24, i1 false)
|
||||
; CHECK: call signext i32 @calleeInt
|
||||
}
|
||||
|
||||
@@ -62,7 +61,7 @@
|
||||
call void @llvm.lifetime.end.p0(i64 28, ptr nonnull %A) #0
|
||||
ret i32 %call
|
||||
; CHECK-LABEL: test3
|
||||
- ; CHECK: %0 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 4
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(28) %A, ptr noundef nonnull align 4 dereferenceable(28) getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 4), i64 28, i1 false)
|
||||
; CHECK: call signext i32 @calleeFloat
|
||||
}
|
||||
|
||||
@@ -75,7 +74,7 @@
|
||||
call void @llvm.lifetime.end.p0(i64 56, ptr nonnull %A) #0
|
||||
ret i32 %call
|
||||
; CHECK-LABEL: test4
|
||||
- ; CHECK: %0 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 0
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(56) %A, ptr noundef nonnull align 8 dereferenceable(56) @__ModuleStringPool, i64 56, i1 false)
|
||||
; CHECK: call signext i32 @calleeDouble
|
||||
}
|
||||
|
||||
@@ -102,11 +101,10 @@
|
||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %B) #0
|
||||
ret i32 %add7
|
||||
; CHECK-LABEL: test5
|
||||
- ; CHECK: %0 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 3
|
||||
- ; CHECK: %1 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 5
|
||||
- ; CHECK: %2 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 1
|
||||
- ; CHECK: %3 = getelementptr { [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 7
|
||||
- ; CHECK: call signext i32 @calleeStr
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) %B, ptr noundef nonnull align 4 dereferenceable(24) getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 3), i64 24, i1 false)
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(28) %C, ptr noundef nonnull align 4 dereferenceable(28) getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 5), i64 28, i1 false)
|
||||
+ ; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(56) %D, ptr noundef nonnull align 8 dereferenceable(56) getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 1), i64 56, i1 false)
|
||||
+ ; CHECK: call signext i32 @calleeStr(ptr noundef nonnull getelementptr inbounds ({ [7 x double], [7 x double], [6 x i32], [6 x i32], [7 x float], [7 x float], [8 x i8], [16 x i8] }, ptr @__ModuleStringPool, i32 0, i32 7))
|
||||
; CHECK: call signext i32 @calleeInt
|
||||
; CHECK: call signext i32 @calleeFloat
|
||||
; CHECK: call signext i32 @calleeDouble
|
||||
diff --git a/llvm/test/CodeGen/PowerPC/mergeable-string-pool.ll b/llvm/test/CodeGen/PowerPC/mergeable-string-pool.ll
|
||||
index a6c5057dde57..7ccdaaf91136 100644
|
||||
--- a/llvm/test/CodeGen/PowerPC/mergeable-string-pool.ll
|
||||
+++ b/llvm/test/CodeGen/PowerPC/mergeable-string-pool.ll
|
||||
@@ -398,16 +398,16 @@ define dso_local signext i32 @array1() local_unnamed_addr #0 {
|
||||
; AIX32: # %bb.0: # %entry
|
||||
; AIX32-NEXT: mflr r0
|
||||
; AIX32-NEXT: stwu r1, -96(r1)
|
||||
-; AIX32-NEXT: lwz r4, L..C0(r2) # @__ModuleStringPool
|
||||
+; AIX32-NEXT: lwz r5, L..C0(r2) # @__ModuleStringPool
|
||||
; AIX32-NEXT: li r6, 372
|
||||
-; AIX32-NEXT: li r5, 12
|
||||
+; AIX32-NEXT: li r4, 12
|
||||
; AIX32-NEXT: addi r3, r1, 64
|
||||
; AIX32-NEXT: stw r0, 104(r1)
|
||||
-; AIX32-NEXT: rlwimi r5, r3, 0, 30, 27
|
||||
-; AIX32-NEXT: lxvw4x vs0, r4, r6
|
||||
-; AIX32-NEXT: stxvw4x vs0, 0, r5
|
||||
-; AIX32-NEXT: li r5, 360
|
||||
-; AIX32-NEXT: lxvw4x vs0, r4, r5
|
||||
+; AIX32-NEXT: rlwimi r4, r3, 0, 30, 27
|
||||
+; AIX32-NEXT: lxvw4x vs0, r5, r6
|
||||
+; AIX32-NEXT: stxvw4x vs0, 0, r4
|
||||
+; AIX32-NEXT: li r4, 360
|
||||
+; AIX32-NEXT: lxvw4x vs0, r5, r4
|
||||
; AIX32-NEXT: stxvw4x vs0, 0, r3
|
||||
; AIX32-NEXT: bl .calleeInt[PR]
|
||||
; AIX32-NEXT: nop
|
||||
--
|
||||
2.42.0
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
|
||||
Name: %{pkg_name}
|
||||
Version: %{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:~rc%{rc_ver}}%{?llvm_snapshot_version_suffix:~%{llvm_snapshot_version_suffix}}
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: The Low Level Virtual Machine
|
||||
|
||||
License: Apache-2.0 WITH LLVM-exception OR NCSA
|
||||
|
@ -113,6 +113,10 @@ Source5: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{maj_ve
|
|||
Source6: release-keys.asc
|
||||
%endif
|
||||
|
||||
# https://github.com/llvm/llvm-project/commit/1184a9cb30e6a12c883b918867f2f06bc3096fc0
|
||||
# This patch will be in 18.1.6
|
||||
Patch1: 0001-PPCMergeStringPool-Avoid-replacing-constant-with-ins.patch
|
||||
|
||||
# RHEL-specific patch to avoid unwanted python3-myst-parser dep
|
||||
Patch101: 0101-Deactivate-markdown-doc.patch
|
||||
|
||||
|
@ -582,6 +586,9 @@ fi
|
|||
|
||||
|
||||
%changelog
|
||||
* Tue May 14 2024 Tom Stellard <tstellar@redhat.com> - 18.1.3-2
|
||||
- Backport fix for rhbz#2275090
|
||||
|
||||
%{?llvm_snapshot_changelog_entry}
|
||||
* Thu Apr 25 2024 Tom Stellard <tstellar@redhat.com> - 18.1.4-1
|
||||
- 18.1.4 Release
|
||||
|
|
Loading…
Reference in a new issue