Skip to content

Commit 36d2e25

Browse files
committedJul 24, 2018
[PredicateInfo] Use custom mangling to support ssa_copy with unnamed types.
This is a workaround and it would be better to fix this generally, but doing it generally is quite tricky. See D48541 and PR38117. Doing it in PredicateInfo directly allows us to use the type address to differentiate different unnamed types, because neither the created declarations nor the ssa_copy calls should be visible after PredicateInfo got destroyed. Reviewers: efriedma, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D49126 llvm-svn: 337828
1 parent 28ded4e commit 36d2e25

File tree

9 files changed

+165
-75
lines changed

9 files changed

+165
-75
lines changed
 

‎llvm/include/llvm/Transforms/Utils/PredicateInfo.h

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "llvm/ADT/DenseMap.h"
5555
#include "llvm/ADT/DenseSet.h"
5656
#include "llvm/ADT/SmallPtrSet.h"
57+
#include "llvm/ADT/SmallSet.h"
5758
#include "llvm/ADT/SmallVector.h"
5859
#include "llvm/ADT/ilist.h"
5960
#include "llvm/ADT/ilist_node.h"
@@ -69,6 +70,7 @@
6970
#include "llvm/IR/Use.h"
7071
#include "llvm/IR/User.h"
7172
#include "llvm/IR/Value.h"
73+
#include "llvm/IR/ValueHandle.h"
7274
#include "llvm/Pass.h"
7375
#include "llvm/PassAnalysisSupport.h"
7476
#include "llvm/Support/Casting.h"
@@ -261,6 +263,8 @@ class PredicateInfo {
261263
// The set of edges along which we can only handle phi uses, due to critical
262264
// edges.
263265
DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeUsesOnly;
266+
// The set of ssa_copy declarations we created with our custom mangling.
267+
SmallSet<AssertingVH<Function>, 20> CreatedDeclarations;
264268
};
265269

266270
// This pass does eager building and then printing of PredicateInfo. It is used

‎llvm/lib/Transforms/Utils/PredicateInfo.cpp

+56-6
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#include "llvm/ADT/STLExtras.h"
1818
#include "llvm/ADT/SmallPtrSet.h"
1919
#include "llvm/ADT/Statistic.h"
20+
#include "llvm/ADT/StringExtras.h"
2021
#include "llvm/Analysis/AssumptionCache.h"
2122
#include "llvm/Analysis/CFG.h"
2223
#include "llvm/IR/AssemblyAnnotationWriter.h"
2324
#include "llvm/IR/DataLayout.h"
2425
#include "llvm/IR/Dominators.h"
2526
#include "llvm/IR/GlobalVariable.h"
2627
#include "llvm/IR/IRBuilder.h"
28+
#include "llvm/IR/InstIterator.h"
2729
#include "llvm/IR/IntrinsicInst.h"
2830
#include "llvm/IR/LLVMContext.h"
2931
#include "llvm/IR/Metadata.h"
@@ -479,6 +481,19 @@ void PredicateInfo::buildPredicateInfo() {
479481
renameUses(OpsToRename);
480482
}
481483

484+
// Create a ssa_copy declaration with custom mangling, because
485+
// Intrinsic::getDeclaration does not handle overloaded unnamed types properly:
486+
// all unnamed types get mangled to the same string. We use the pointer
487+
// to the type as name here, as it guarantees unique names for different
488+
// types and we remove the declarations when destroying PredicateInfo.
489+
// It is a workaround for PR38117, because solving it in a fully general way is
490+
// tricky (FIXME).
491+
static Function *getCopyDeclaration(Module *M, Type *Ty) {
492+
std::string Name = "llvm.ssa.copy." + utostr((uintptr_t) Ty);
493+
return cast<Function>(M->getOrInsertFunction(
494+
Name, getType(M->getContext(), Intrinsic::ssa_copy, Ty)));
495+
}
496+
482497
// Given the renaming stack, make all the operands currently on the stack real
483498
// by inserting them into the IR. Return the last operation's value.
484499
Value *PredicateInfo::materializeStack(unsigned int &Counter,
@@ -507,8 +522,9 @@ Value *PredicateInfo::materializeStack(unsigned int &Counter,
507522
// order in the case of multiple predicateinfo in the same block.
508523
if (isa<PredicateWithEdge>(ValInfo)) {
509524
IRBuilder<> B(getBranchTerminator(ValInfo));
510-
Function *IF = Intrinsic::getDeclaration(
511-
F.getParent(), Intrinsic::ssa_copy, Op->getType());
525+
Function *IF = getCopyDeclaration(F.getParent(), Op->getType());
526+
if (IF->user_begin() == IF->user_end())
527+
CreatedDeclarations.insert(IF);
512528
CallInst *PIC =
513529
B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
514530
PredicateMap.insert({PIC, ValInfo});
@@ -518,8 +534,9 @@ Value *PredicateInfo::materializeStack(unsigned int &Counter,
518534
assert(PAssume &&
519535
"Should not have gotten here without it being an assume");
520536
IRBuilder<> B(PAssume->AssumeInst);
521-
Function *IF = Intrinsic::getDeclaration(
522-
F.getParent(), Intrinsic::ssa_copy, Op->getType());
537+
Function *IF = getCopyDeclaration(F.getParent(), Op->getType());
538+
if (IF->user_begin() == IF->user_end())
539+
CreatedDeclarations.insert(IF);
523540
CallInst *PIC = B.CreateCall(IF, Op);
524541
PredicateMap.insert({PIC, ValInfo});
525542
Result.Def = PIC;
@@ -704,7 +721,22 @@ PredicateInfo::PredicateInfo(Function &F, DominatorTree &DT,
704721
buildPredicateInfo();
705722
}
706723

707-
PredicateInfo::~PredicateInfo() {}
724+
// Remove all declarations we created . The PredicateInfo consumers are
725+
// responsible for remove the ssa_copy calls created.
726+
PredicateInfo::~PredicateInfo() {
727+
// Collect function pointers in set first, as SmallSet uses a SmallVector
728+
// internally and we have to remove the asserting value handles first.
729+
SmallPtrSet<Function *, 20> FunctionPtrs;
730+
for (auto &F : CreatedDeclarations)
731+
FunctionPtrs.insert(&*F);
732+
CreatedDeclarations.clear();
733+
734+
for (Function *F : FunctionPtrs) {
735+
assert(F->user_begin() == F->user_end() &&
736+
"PredicateInfo consumer did not remove all SSA copies.");
737+
F->eraseFromParent();
738+
}
739+
}
708740

709741
void PredicateInfo::verifyPredicateInfo() const {}
710742

@@ -722,13 +754,29 @@ void PredicateInfoPrinterLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
722754
AU.addRequired<AssumptionCacheTracker>();
723755
}
724756

757+
// Replace ssa_copy calls created by PredicateInfo with their operand.
758+
static void replaceCreatedSSACopys(PredicateInfo &PredInfo, Function &F) {
759+
for (auto I = inst_begin(F), E = inst_end(F); I != E;) {
760+
Instruction *Inst = &*I++;
761+
const auto *PI = PredInfo.getPredicateInfoFor(Inst);
762+
auto *II = dyn_cast<IntrinsicInst>(Inst);
763+
if (!PI || !II || II->getIntrinsicID() != Intrinsic::ssa_copy)
764+
continue;
765+
766+
Inst->replaceAllUsesWith(II->getOperand(0));
767+
Inst->eraseFromParent();
768+
}
769+
}
770+
725771
bool PredicateInfoPrinterLegacyPass::runOnFunction(Function &F) {
726772
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
727773
auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
728774
auto PredInfo = make_unique<PredicateInfo>(F, DT, AC);
729775
PredInfo->print(dbgs());
730776
if (VerifyPredicateInfo)
731777
PredInfo->verifyPredicateInfo();
778+
779+
replaceCreatedSSACopys(*PredInfo, F);
732780
return false;
733781
}
734782

@@ -737,8 +785,10 @@ PreservedAnalyses PredicateInfoPrinterPass::run(Function &F,
737785
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
738786
auto &AC = AM.getResult<AssumptionAnalysis>(F);
739787
OS << "PredicateInfo for function: " << F.getName() << "\n";
740-
make_unique<PredicateInfo>(F, DT, AC)->print(OS);
788+
auto PredInfo = make_unique<PredicateInfo>(F, DT, AC);
789+
PredInfo->print(OS);
741790

791+
replaceCreatedSSACopys(*PredInfo, F);
742792
return PreservedAnalyses::all();
743793
}
744794

‎llvm/test/Other/debugcounter-predicateinfo.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ define fastcc void @barney() {
88
; CHECK-NEXT: br label [[BB22:%.*]]
99
; CHECK: bb22:
1010
; CHECK-NEXT: [[TMP23:%.*]] = icmp eq i32 undef, 2
11-
; CHECK: [[TMP23_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP23]])
11+
; CHECK: [[TMP23_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP23]])
1212
; CHECK-NEXT: br i1 [[TMP23]], label [[BB29:%.*]], label [[BB35:%.*]]
1313
; CHECK: bb29:
14-
; CHECK: [[TMP23_0_1:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP23_0]])
14+
; CHECK: [[TMP23_0_1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP23_0]])
1515
; CHECK-NEXT: br i1 [[TMP23]], label [[BB33:%.*]], label [[BB35]]
1616
; CHECK: bb33:
1717
; CHECK-NEXT: br i1 [[TMP23_0_1]], label [[BB35]], label [[BB35]]

‎llvm/test/Transforms/NewGVN/pr33305.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ define i32 @main() local_unnamed_addr #0 {
7676
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
7777
; CHECK: if.then:
7878
; CHECK-NEXT: [[PUTS2:%.*]] = tail call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @str.2, i64 0, i64 0))
79-
; CHECK-NEXT: tail call void @abort() #4
79+
; CHECK-NEXT: tail call void @abort()
8080
; CHECK-NEXT: unreachable
8181
; CHECK: if.end:
8282
; CHECK-NEXT: [[PUTS:%.*]] = tail call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str, i64 0, i64 0))

‎llvm/test/Transforms/Util/PredicateInfo/condprop.ll

+27-27
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ define void @test3(i32 %x, i32 %y) {
9898
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
9999
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
100100
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
101-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
102-
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
103-
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
104-
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
105-
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
101+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
102+
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
103+
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
104+
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
105+
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
106106
; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]]
107107
; CHECK: both_zero:
108108
; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
@@ -139,7 +139,7 @@ define void @test4(i1 %b, i32 %x) {
139139
; CHECK-NEXT: i32 3, label [[CASE3]]
140140
; CHECK-NEXT: i32 4, label [[DEFAULT:%.*]]
141141
; CHECK-NEXT: ] Edge: [label [[SW]],label %case1] }
142-
; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X:%.*]])
142+
; CHECK-NEXT: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X:%.*]])
143143
; CHECK-NEXT: switch i32 [[X]], label [[DEFAULT]] [
144144
; CHECK-NEXT: i32 0, label [[CASE0]]
145145
; CHECK-NEXT: i32 1, label [[CASE1]]
@@ -186,10 +186,10 @@ case3:
186186
define i1 @test5(i32 %x, i32 %y) {
187187
; CHECK-LABEL: @test5(
188188
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
189-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
190-
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
191-
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
192-
; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
189+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
190+
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
191+
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
192+
; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
193193
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
194194
; CHECK: same:
195195
; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[X_0]], [[Y_0]]
@@ -259,10 +259,10 @@ different:
259259
define i1 @test7(i32 %x, i32 %y) {
260260
; CHECK-LABEL: @test7(
261261
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
262-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
263-
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
264-
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
265-
; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
262+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
263+
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
264+
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
265+
; CHECK: [[Y_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
266266
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
267267
; CHECK: same:
268268
; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X_0]], [[Y_0]]
@@ -286,10 +286,10 @@ different:
286286
define i1 @test7_fp(float %x, float %y) {
287287
; CHECK-LABEL: @test7_fp(
288288
; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]]
289-
; CHECK: [[X_0:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
290-
; CHECK: [[X_1:%.*]] = call float @llvm.ssa.copy.f32(float [[X]])
291-
; CHECK: [[Y_0:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
292-
; CHECK: [[Y_1:%.*]] = call float @llvm.ssa.copy.f32(float [[Y]])
289+
; CHECK: [[X_0:%.*]] = call float @llvm.ssa.copy.{{.+}}(float [[X]])
290+
; CHECK: [[X_1:%.*]] = call float @llvm.ssa.copy.{{.+}}(float [[X]])
291+
; CHECK: [[Y_0:%.*]] = call float @llvm.ssa.copy.{{.+}}(float [[Y]])
292+
; CHECK: [[Y_1:%.*]] = call float @llvm.ssa.copy.{{.+}}(float [[Y]])
293293
; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]]
294294
; CHECK: same:
295295
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ule float [[X_0]], [[Y_0]]
@@ -359,8 +359,8 @@ different:
359359
define i32 @test9(i32 %i, i32 %j) {
360360
; CHECK-LABEL: @test9(
361361
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
362-
; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
363-
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
362+
; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[I]])
363+
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[J]])
364364
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
365365
; CHECK: cond_true:
366366
; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
@@ -382,8 +382,8 @@ ret:
382382
define i32 @test10(i32 %j, i32 %i) {
383383
; CHECK-LABEL: @test10(
384384
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]]
385-
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[J]])
386-
; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[I]])
385+
; CHECK: [[J_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[J]])
386+
; CHECK: [[I_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[I]])
387387
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]]
388388
; CHECK: cond_true:
389389
; CHECK-NEXT: [[DIFF:%.*]] = sub i32 [[I_0]], [[J_0]]
@@ -409,14 +409,14 @@ define i32 @test11(i32 %x) {
409409
; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar()
410410
; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar()
411411
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]]
412-
; CHECK: [[V0_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0]])
413-
; CHECK: [[V1_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V1]])
412+
; CHECK: [[V0_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[V0]])
413+
; CHECK: [[V1_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[V1]])
414414
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]]
415415
; CHECK: cond_true:
416416
; CHECK-NEXT: ret i32 [[V1_0]]
417417
; CHECK: next:
418418
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0_0]]
419-
; CHECK: [[V0_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[V0_0]])
419+
; CHECK: [[V0_0_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[V0_0]])
420420
; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]]
421421
; CHECK: cond_true2:
422422
; CHECK-NEXT: ret i32 [[V0_0_1]]
@@ -445,8 +445,8 @@ next2:
445445
define i32 @test12(i32 %x) {
446446
; CHECK-LABEL: @test12(
447447
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
448-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
449-
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
448+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
449+
; CHECK: [[X_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
450450
; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
451451
; CHECK: cond_true:
452452
; CHECK-NEXT: br label [[RET:%.*]]

‎llvm/test/Transforms/Util/PredicateInfo/diamond.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ define i1 @f(i32 %x, i1 %y) {
55
; CHECK-NEXT: br i1 [[Y:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
66
; CHECK: bb0:
77
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0
8-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
8+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
99
; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]]
1010
; CHECK: bb1:
1111
; CHECK-NEXT: [[X2:%.*]] = add nuw nsw i32 [[X]], 1
1212
; CHECK-NEXT: [[CMP2:%.*]] = icmp sge i32 [[X2]], 2
13-
; CHECK: [[X2_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X2]])
13+
; CHECK: [[X2_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X2]])
1414
; CHECK-NEXT: br i1 [[CMP2]], label [[BB2]], label [[BB3]]
1515
; CHECK: bb2:
1616
; CHECK-NEXT: [[X3:%.*]] = phi i32 [ [[X_0]], [[BB0]] ], [ [[X2_0]], [[BB1]] ]
@@ -38,12 +38,12 @@ define i1 @g(i32 %x, i1 %y) {
3838
; CHECK-NEXT: br i1 [[Y:%.*]], label [[BB0:%.*]], label [[BB1:%.*]]
3939
; CHECK: bb0:
4040
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[X:%.*]], 0
41-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
41+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
4242
; CHECK-NEXT: br i1 [[CMP]], label [[BB3:%.*]], label [[BB2:%.*]]
4343
; CHECK: bb1:
4444
; CHECK-NEXT: [[X2:%.*]] = add nuw nsw i32 [[X]], 1
4545
; CHECK-NEXT: [[CMP2:%.*]] = icmp sge i32 [[X2]], 2
46-
; CHECK: [[X2_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X2]])
46+
; CHECK: [[X2_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X2]])
4747
; CHECK-NEXT: br i1 [[CMP2]], label [[BB3]], label [[BB2]]
4848
; CHECK: bb2:
4949
; CHECK-NEXT: [[X3:%.*]] = phi i32 [ [[X_0]], [[BB0]] ], [ [[X2_0]], [[BB1]] ]

‎llvm/test/Transforms/Util/PredicateInfo/edge.ll

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define i32 @f1(i32 %x) {
55
; CHECK-LABEL: @f1(
66
; CHECK-NEXT: bb0:
77
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
8-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
8+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
99
; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB1:%.*]]
1010
; CHECK: bb1:
1111
; CHECK-NEXT: br label [[BB2]]
@@ -29,7 +29,7 @@ define i32 @f2(i32 %x) {
2929
; CHECK-LABEL: @f2(
3030
; CHECK-NEXT: bb0:
3131
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X:%.*]], 0
32-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
32+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
3333
; CHECK-NEXT: br i1 [[CMP]], label [[BB1:%.*]], label [[BB2:%.*]]
3434
; CHECK: bb1:
3535
; CHECK-NEXT: br label [[BB2]]
@@ -52,7 +52,7 @@ bb2:
5252
define i32 @f3(i32 %x) {
5353
; CHECK-LABEL: @f3(
5454
; CHECK-NEXT: bb0:
55-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X:%.*]])
55+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X:%.*]])
5656
; CHECK-NEXT: switch i32 [[X]], label [[BB1:%.*]] [
5757
; CHECK-NEXT: i32 0, label [[BB2:%.*]]
5858
; CHECK-NEXT: ]
@@ -78,7 +78,7 @@ define double @fcmp_oeq_not_zero(double %x, double %y) {
7878
; CHECK-LABEL: @fcmp_oeq_not_zero(
7979
; CHECK-NEXT: entry:
8080
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y:%.*]], 2.000000e+00
81-
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Y]])
81+
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Y]])
8282
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
8383
; CHECK: if:
8484
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y_0]]
@@ -105,7 +105,7 @@ define double @fcmp_une_not_zero(double %x, double %y) {
105105
; CHECK-LABEL: @fcmp_une_not_zero(
106106
; CHECK-NEXT: entry:
107107
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y:%.*]], 2.000000e+00
108-
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Y]])
108+
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Y]])
109109
; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
110110
; CHECK: else:
111111
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y_0]]
@@ -132,7 +132,7 @@ define double @fcmp_oeq_zero(double %x, double %y) {
132132
; CHECK-LABEL: @fcmp_oeq_zero(
133133
; CHECK-NEXT: entry:
134134
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y:%.*]], 0.000000e+00
135-
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Y]])
135+
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Y]])
136136
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
137137
; CHECK: if:
138138
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y_0]]
@@ -159,7 +159,7 @@ define double @fcmp_une_zero(double %x, double %y) {
159159
; CHECK-LABEL: @fcmp_une_zero(
160160
; CHECK-NEXT: entry:
161161
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y:%.*]], -0.000000e+00
162-
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Y]])
162+
; CHECK: [[Y_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Y]])
163163
; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
164164
; CHECK: else:
165165
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Y_0]]
@@ -188,7 +188,7 @@ define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2)
188188
; CHECK-NEXT: entry:
189189
; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1:%.*]], [[Z2:%.*]]
190190
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y:%.*]], [[Z]]
191-
; CHECK: [[Z_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Z]])
191+
; CHECK: [[Z_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Z]])
192192
; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[RETURN:%.*]]
193193
; CHECK: if:
194194
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Z_0]]
@@ -217,7 +217,7 @@ define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2)
217217
; CHECK-NEXT: entry:
218218
; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1:%.*]], [[Z2:%.*]]
219219
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y:%.*]], [[Z]]
220-
; CHECK: [[Z_0:%.*]] = call double @llvm.ssa.copy.f64(double [[Z]])
220+
; CHECK: [[Z_0:%.*]] = call double @llvm.ssa.copy.{{.+}}(double [[Z]])
221221
; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[ELSE:%.*]]
222222
; CHECK: else:
223223
; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X:%.*]], [[Z_0]]

‎llvm/test/Transforms/Util/PredicateInfo/testandor.ll

+26-26
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ define void @testor(i32 %x, i32 %y) {
1010
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
1111
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
1212
; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
13-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
14-
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
15-
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
16-
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
17-
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
13+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
14+
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
15+
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
16+
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
17+
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
1818
; CHECK-NEXT: br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
1919
; CHECK: oneof:
2020
; CHECK-NEXT: call void @foo(i1 [[XZ]])
@@ -54,11 +54,11 @@ define void @testand(i32 %x, i32 %y) {
5454
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
5555
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
5656
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
57-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
58-
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
59-
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
60-
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
61-
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
57+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
58+
; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
59+
; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
60+
; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
61+
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
6262
; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
6363
; CHECK: both:
6464
; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
@@ -98,11 +98,11 @@ define void @testandsame(i32 %x, i32 %y) {
9898
; CHECK-NEXT: [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0
9999
; CHECK-NEXT: [[XLT:%.*]] = icmp slt i32 [[X]], 100
100100
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XGT]], [[XLT]]
101-
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
102-
; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X_0]])
103-
; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XGT]])
104-
; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XLT]])
105-
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
101+
; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
102+
; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X_0]])
103+
; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XGT]])
104+
; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XLT]])
105+
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
106106
; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
107107
; CHECK: both:
108108
; CHECK-NEXT: call void @foo(i1 [[XGT_0]])
@@ -136,17 +136,17 @@ define void @testandassume(i32 %x, i32 %y) {
136136
; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
137137
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
138138
; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
139-
; CHECK: [[TMP1:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[X]])
140-
; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[Y]])
141-
; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[XZ]])
142-
; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[YZ]])
143-
; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
139+
; CHECK: [[TMP1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
140+
; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
141+
; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
142+
; CHECK: [[TMP4:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
143+
; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
144144
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP5]])
145-
; CHECK: [[DOT0:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP1]])
146-
; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.i32(i32 [[TMP2]])
147-
; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP3]])
148-
; CHECK: [[DOT03:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP4]])
149-
; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[TMP5]])
145+
; CHECK: [[DOT0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP1]])
146+
; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP2]])
147+
; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP3]])
148+
; CHECK: [[DOT03:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP4]])
149+
; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP5]])
150150
; CHECK-NEXT: br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
151151
; CHECK: both:
152152
; CHECK-NEXT: call void @foo(i1 [[DOT02]])
@@ -182,7 +182,7 @@ define void @testorassume(i32 %x, i32 %y) {
182182
; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
183183
; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
184184
; CHECK-NEXT: call void @llvm.assume(i1 [[Z]])
185-
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.i1(i1 [[Z]])
185+
; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
186186
; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
187187
; CHECK: both:
188188
; CHECK-NEXT: call void @foo(i1 [[XZ]])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: opt < %s -print-predicateinfo 2>&1 | FileCheck %s
2+
3+
%1 = type opaque
4+
%0 = type opaque
5+
6+
; Check we can use ssa.copy with unnamed types.
7+
8+
; CHECK-LABEL: bb:
9+
; CHECK: Has predicate info
10+
; CHECK: branch predicate info { TrueEdge: 1 Comparison: %cmp1 = icmp ne %0* %arg, null Edge: [label %bb,label %bb1] }
11+
; CHECK-NEXT: %arg.0 = call %0* @llvm.ssa.copy.{{.+}}(%0* %arg)
12+
13+
; CHECK-LABEL: bb1:
14+
; CHECK: Has predicate info
15+
; CHECK-NEXT: branch predicate info { TrueEdge: 0 Comparison: %cmp2 = icmp ne %1* null, %tmp Edge: [label %bb1,label %bb3] }
16+
; CHECK-NEXT: %tmp.0 = call %1* @llvm.ssa.copy.{{.+}}(%1* %tmp)
17+
18+
define void @f0(%0* %arg, %1* %tmp) {
19+
bb:
20+
%cmp1 = icmp ne %0* %arg, null
21+
br i1 %cmp1, label %bb1, label %bb2
22+
23+
bb1: ; preds = %bb
24+
%cmp2 = icmp ne %1* null, %tmp
25+
br i1 %cmp2, label %bb2, label %bb3
26+
27+
bb2: ; preds = %bb
28+
ret void
29+
30+
bb3: ; preds = %bb
31+
%u1 = call i8* @fun(%1* %tmp)
32+
%tmp2 = bitcast %0* %arg to i8*
33+
ret void
34+
}
35+
36+
declare i8* @fun(%1*)

0 commit comments

Comments
 (0)
Please sign in to comment.