aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2015-06-12 15:57:35 +0000
committerTim Northover <tnorthover@apple.com>2015-06-12 15:57:35 +0000
commit2f8c90e9db7169a261c57bf0a70873975ebe3ac6 (patch)
treea2b60b9087a181d5ced2fc6390e659508de24192
parent93b572500c019f10778af3dad0ec3a9ff9014e00 (diff)
downloadllvm-2f8c90e9db7169a261c57bf0a70873975ebe3ac6.zip
llvm-2f8c90e9db7169a261c57bf0a70873975ebe3ac6.tar.gz
llvm-2f8c90e9db7169a261c57bf0a70873975ebe3ac6.tar.bz2
Merging r236457 and r236635:
------------------------------------------------------------------------ r236457 | tnorthover | 2015-05-04 13:41:51 -0700 (Mon, 04 May 2015) | 9 lines CodeGen: match up correct insertvalue indices when assessing tail calls. When deciding whether a value comes from the aggregate or inserted value of an insertvalue instruction, we compare the indices against those of the location we're interested in. One of the lists needs reversing because the input data is backwards (so that modifications take place at the end of the SmallVector), but we were reversing both before leading to incorrect results. ------------------------------------------------------------------------ r236635 | tnorthover | 2015-05-06 13:07:38 -0700 (Wed, 06 May 2015) | 12 lines CodeGen: move over-zealous assert into actual if statement. It's quite possible to encounter an insertvalue instruction that's more deeply nested than the value we're looking for, but when that happens we really mustn't compare beyond the end of the index array. Since I couldn't see any guarantees about what comparisons std::equal makes, we probably need to directly check the size beforehand. In practice, I suspect most std::equal implementations would probably bail early, which would be OK. But just in case... rdar://20834485 llvm-svn: 239611
-rw-r--r--llvm/lib/CodeGen/Analysis.cpp4
-rw-r--r--llvm/test/CodeGen/AArch64/tail-call.ll38
2 files changed, 40 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp
index 2e8af9e..61ead21 100644
--- a/llvm/lib/CodeGen/Analysis.cpp
+++ b/llvm/lib/CodeGen/Analysis.cpp
@@ -295,8 +295,8 @@ static const Value *getNoopInput(const Value *V,
} else if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(V)) {
// Value may come from either the aggregate or the scalar
ArrayRef<unsigned> InsertLoc = IVI->getIndices();
- if (std::equal(InsertLoc.rbegin(), InsertLoc.rend(),
- ValLoc.rbegin())) {
+ if (ValLoc.size() >= InsertLoc.size() &&
+ std::equal(InsertLoc.begin(), InsertLoc.end(), ValLoc.rbegin())) {
// The type being inserted is a nested sub-type of the aggregate; we
// have to remove those initial indices to get the location we're
// interested in for the operand.
diff --git a/llvm/test/CodeGen/AArch64/tail-call.ll b/llvm/test/CodeGen/AArch64/tail-call.ll
index 7fb3954..e576615 100644
--- a/llvm/test/CodeGen/AArch64/tail-call.ll
+++ b/llvm/test/CodeGen/AArch64/tail-call.ll
@@ -103,3 +103,41 @@ define fastcc void @caller_weak() {
tail call void @callee_weak()
ret void
}
+
+declare { [2 x float] } @get_vec2()
+
+define { [3 x float] } @test_add_elem() {
+; CHECK-LABEL: test_add_elem:
+; CHECK: bl get_vec2
+; CHECK: fmov s2, #1.0
+; CHECK: ret
+
+ %call = tail call { [2 x float] } @get_vec2()
+ %arr = extractvalue { [2 x float] } %call, 0
+ %arr.0 = extractvalue [2 x float] %arr, 0
+ %arr.1 = extractvalue [2 x float] %arr, 1
+
+ %res.0 = insertvalue { [3 x float] } undef, float %arr.0, 0, 0
+ %res.01 = insertvalue { [3 x float] } %res.0, float %arr.1, 0, 1
+ %res.012 = insertvalue { [3 x float] } %res.01, float 1.000000e+00, 0, 2
+ ret { [3 x float] } %res.012
+}
+
+declare double @get_double()
+define { double, [2 x double] } @test_mismatched_insert() {
+; CHECK-LABEL: test_mismatched_insert:
+; CHECK: bl get_double
+; CHECK: bl get_double
+; CHECK: bl get_double
+; CHECK: ret
+
+ %val0 = call double @get_double()
+ %val1 = call double @get_double()
+ %val2 = tail call double @get_double()
+
+ %res.0 = insertvalue { double, [2 x double] } undef, double %val0, 0
+ %res.01 = insertvalue { double, [2 x double] } %res.0, double %val1, 1, 0
+ %res.012 = insertvalue { double, [2 x double] } %res.01, double %val2, 1, 1
+
+ ret { double, [2 x double] } %res.012
+}