-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IR] Fix nested constant to instruction conversion #69682
Conversation
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/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-transforms Author: Wenju He (wenju-he) Changes[IR] Fix nested constant to instruction conversion Fix two issues:
Full diff: https://github.com/llvm/llvm-project/pull/69682.diff 2 Files Affected:
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:
|
llvm/lib/IR/ReplaceConstant.cpp
Outdated
U.set(NI); | ||
auto NewInsts = expandUser(BI, C); | ||
for (auto *NI : NewInsts) | ||
NI->setDebugLoc(BI->getDebugLoc()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For phi nodes this will take the debug loc from the terminator of the incoming block rather than the phi node -- is that intended?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review. I didn't notice this problem. I've updated to use debug loc from the original inst
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Fix two issues:
created instructions to worklist so that constant used in them will
be converted.