[llvm] [IR] Fix nested constant to instruction conversion (PR #69682)
Wenju He via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 20 01:08:08 PDT 2023
https://github.com/wenju-he updated https://github.com/llvm/llvm-project/pull/69682
>From 88d167cb853ba5cf9b1a9757afe4c642f37e475c Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Fri, 20 Oct 2023 14:28:22 +0800
Subject: [PATCH 1/2] [IR] Fix nested constant to instruction conversion
Fix two issues:
* If a constant is used in another constant, we need to insert newly
created instructions to worklist so that constant used in them will
be converted.
* Set debug info of original instruction to newly created instructions.
---
llvm/lib/IR/ReplaceConstant.cpp | 25 ++++++++++++-------
.../LowerTypeTests/function-weak.ll | 13 ++++++++++
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/IR/ReplaceConstant.cpp b/llvm/lib/IR/ReplaceConstant.cpp
index 58aa040eb032a87..7a98d9019b930b4 100644
--- a/llvm/lib/IR/ReplaceConstant.cpp
+++ b/llvm/lib/IR/ReplaceConstant.cpp
@@ -22,24 +22,29 @@ static bool isExpandableUser(User *U) {
return isa<ConstantExpr>(U) || isa<ConstantAggregate>(U);
}
-static Instruction *expandUser(Instruction *InsertPt, Constant *C) {
+static SmallVector<Instruction *, 4> expandUser(Instruction *InsertPt,
+ Constant *C) {
+ SmallVector<Instruction *, 4> NewInsts;
if (auto *CE = dyn_cast<ConstantExpr>(C)) {
- return CE->getAsInstruction(InsertPt);
+ NewInsts.push_back(CE->getAsInstruction(InsertPt));
} else if (isa<ConstantStruct>(C) || isa<ConstantArray>(C)) {
Value *V = PoisonValue::get(C->getType());
- for (auto [Idx, Op] : enumerate(C->operands()))
+ for (auto [Idx, Op] : enumerate(C->operands())) {
V = InsertValueInst::Create(V, Op, Idx, "", InsertPt);
- return cast<Instruction>(V);
+ NewInsts.push_back(cast<Instruction>(V));
+ }
} else if (isa<ConstantVector>(C)) {
Type *IdxTy = Type::getInt32Ty(C->getContext());
Value *V = PoisonValue::get(C->getType());
- for (auto [Idx, Op] : enumerate(C->operands()))
+ for (auto [Idx, Op] : enumerate(C->operands())) {
V = InsertElementInst::Create(V, Op, ConstantInt::get(IdxTy, Idx), "",
InsertPt);
- return cast<Instruction>(V);
+ NewInsts.push_back(cast<Instruction>(V));
+ }
} else {
llvm_unreachable("Not an expandable user");
}
+ return NewInsts;
}
bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) {
@@ -85,9 +90,11 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) {
if (auto *C = dyn_cast<Constant>(U.get())) {
if (ExpandableUsers.contains(C)) {
Changed = true;
- Instruction *NI = expandUser(BI, C);
- InstructionWorklist.insert(NI);
- U.set(NI);
+ auto NewInsts = expandUser(BI, C);
+ for (auto *NI : NewInsts)
+ NI->setDebugLoc(BI->getDebugLoc());
+ InstructionWorklist.insert(NewInsts.begin(), NewInsts.end());
+ U.set(NewInsts.back());
}
}
}
diff --git a/llvm/test/Transforms/LowerTypeTests/function-weak.ll b/llvm/test/Transforms/LowerTypeTests/function-weak.ll
index c765937f1991340..5f9041cd21b3c80 100644
--- a/llvm/test/Transforms/LowerTypeTests/function-weak.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function-weak.ll
@@ -48,6 +48,19 @@ entry:
ret void
}
+define void @struct() {
+; CHECK-LABEL: define void @struct() {
+; CHECK: %0 = select i1 icmp ne (ptr @f, ptr null), ptr @.cfi.jumptable, ptr null
+; CHECK-NEXT: %1 = icmp ne ptr %0, null
+; CHECK-NEXT: %2 = insertvalue { i1, i8 } poison, i1 %1, 0
+; CHECK-NEXT: %3 = insertvalue { i1, i8 } %2, i8 0, 1
+; CHECK-NEXT: %x = extractvalue { i1, i8 } %3, 0
+
+entry:
+ %x = extractvalue { i1, i8 } { i1 icmp ne (ptr @f, ptr null), i8 0 }, 0
+ ret void
+}
+
define void @phi(i1 %c) {
; CHECK-LABEL: define void @phi(i1 %c) {
; CHECK: entry:
>From 551d0c00bf6146d7e0567bb8201d466e2d68412f Mon Sep 17 00:00:00 2001
From: Wenju He <wenju.he at intel.com>
Date: Fri, 20 Oct 2023 16:07:53 +0800
Subject: [PATCH 2/2] use DebugLoc of original inst instead of insert point
---
llvm/lib/IR/ReplaceConstant.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/IR/ReplaceConstant.cpp b/llvm/lib/IR/ReplaceConstant.cpp
index 7a98d9019b930b4..42dec7c72328ea8 100644
--- a/llvm/lib/IR/ReplaceConstant.cpp
+++ b/llvm/lib/IR/ReplaceConstant.cpp
@@ -78,6 +78,7 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) {
bool Changed = false;
while (!InstructionWorklist.empty()) {
Instruction *I = InstructionWorklist.pop_back_val();
+ DebugLoc Loc = I->getDebugLoc();
for (Use &U : I->operands()) {
auto *BI = I;
if (auto *Phi = dyn_cast<PHINode>(I)) {
@@ -92,7 +93,7 @@ bool convertUsersOfConstantsToInstructions(ArrayRef<Constant *> Consts) {
Changed = true;
auto NewInsts = expandUser(BI, C);
for (auto *NI : NewInsts)
- NI->setDebugLoc(BI->getDebugLoc());
+ NI->setDebugLoc(Loc);
InstructionWorklist.insert(NewInsts.begin(), NewInsts.end());
U.set(NewInsts.back());
}
More information about the llvm-commits
mailing list