summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/SCCP/switch-undef-constantfoldterminator.ll47
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SCCP/switch-undef-constantfoldterminator.ll b/llvm/test/Transforms/SCCP/switch-undef-constantfoldterminator.ll
new file mode 100644
index 00000000000..169f0e83f1f
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/switch-undef-constantfoldterminator.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -ipsccp -S | FileCheck %s
+
+; This test case used to end up like this:
+;
+; While deleting: label %lor.rhs
+; Use still stuck around after Def is destroyed: br i1 undef, label %lor.rhs, label %land.end
+; opt: ../lib/IR/Value.cpp: llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
+;
+; due to ConstantFoldTerminator rewriting the switch into
+;
+; br i1 undef, label %lor.rhs, label %land.end
+;
+; while SCCP implementation relied on the terminator to always be folded into
+; an unconditional branch when ConstantFoldTerminator returned true.
+
+define void @f4() {
+; CHECK-LABEL: define void @f4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CALL:%.*]] = call i16 @f3(i16 undef)
+; CHECK-NEXT: ret void
+;
+entry:
+ %call = call i16 @f3(i16 undef)
+ ret void
+}
+
+define internal i16 @f3(i16 %p1) {
+; CHECK-LABEL: define internal i16 @f3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LAND_END:%.*]]
+; CHECK: land.end:
+; CHECK-NEXT: ret i16 undef
+;
+entry:
+ switch i16 %p1, label %land.end [
+ i16 0, label %land.end
+ i16 1, label %lor.rhs
+ ]
+
+lor.rhs:
+ br label %land.end
+
+land.end:
+ ret i16 0
+}
+
OpenPOWER on IntegriCloud