diff options
author | Hal Finkel <hfinkel@anl.gov> | 2016-09-07 21:38:22 +0000 |
---|---|---|
committer | Hal Finkel <hfinkel@anl.gov> | 2016-09-07 21:38:22 +0000 |
commit | ac5803ba918eeb133b1a0665eaf0e430f714b4d1 (patch) | |
tree | e31abd2f48fd2834fa908a91515d80b6d08806bb | |
parent | 109f4f35095dece3a05c88f6a40a7ad6ad07951f (diff) | |
download | bcm5719-llvm-ac5803ba918eeb133b1a0665eaf0e430f714b4d1.tar.gz bcm5719-llvm-ac5803ba918eeb133b1a0665eaf0e430f714b4d1.zip |
[SimplifyCFG] Don't try to create metadata-valued PHIs
We can't create metadata-valued PHIs; don't try to do so when sinking.
I created a test case for this using the @llvm.type.test intrinsic, because it
takes a metadata parameter and does not have severe side effects (thus
SimplifyCFG is willing to otherwise sink it).
Previously, running the test case would crash with:
Invalid use of metadata!
%.sink = select i1 %flag, metadata <...>, metadata <0x4e45dc0>
LLVM ERROR: Broken function found, compilation aborted!
llvm-svn: 280866
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 4 | ||||
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/no-md-sink.ll | 51 |
2 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index e5da77e6319..5785968114c 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1338,6 +1338,10 @@ HoistTerminator: // FIXME: This should be promoted to Instruction. static bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx) { + // We can't have a PHI with a metadata type. + if (I->getOperand(OpIdx)->getType()->isMetadataTy()) + return false; + // Early exit. if (!isa<Constant>(I->getOperand(OpIdx))) return true; diff --git a/llvm/test/Transforms/SimplifyCFG/no-md-sink.ll b/llvm/test/Transforms/SimplifyCFG/no-md-sink.ll new file mode 100644 index 00000000000..b60327073ec --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/no-md-sink.ll @@ -0,0 +1,51 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +define i1 @test1(i1 zeroext %flag, i8* %y) #0 { +entry: + br i1 %flag, label %if.then, label %if.else + +if.then: + %r = call i1 @llvm.type.test(i8* %y, metadata !0) + br label %if.end + +if.else: + %s = call i1 @llvm.type.test(i8* %y, metadata !1) + br label %if.end + +if.end: + %t = phi i1 [ %s, %if.else ], [ %r, %if.then ] + ret i1 %t +} + +!0 = !{i32 0, !"typeid1"} +!1 = !{i32 4, !"typeid1"} + +declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone + +; CHECK-LABEL: test1 +; CHECK: @llvm.type.test +; CHECK: @llvm.type.test +; CHECK: ret i1 + +define i1 @test2(i1 zeroext %flag, i8* %y, i8* %z) #0 { +entry: + br i1 %flag, label %if.then, label %if.else + +if.then: + %r = call i1 @llvm.type.test(i8* %y, metadata !0) + br label %if.end + +if.else: + %s = call i1 @llvm.type.test(i8* %z, metadata !0) + br label %if.end + +if.end: + %t = phi i1 [ %s, %if.else ], [ %r, %if.then ] + ret i1 %t +} + +; CHECK-LABEL: test2 +; CHECK: %[[S:[a-z0-9.]+]] = select i1 %flag, i8* %y, i8* %z +; CHECK: %[[R:[a-z0-9.]+]] = call i1 @llvm.type.test(i8* %[[S]], metadata !0) +; CHECK: ret i1 %[[R]] + |