CodeGen: move over-zealous assert into actual if statement.
authorTim Northover <tnorthover@apple.com>
Wed, 6 May 2015 20:07:38 +0000 (20:07 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 6 May 2015 20:07:38 +0000 (20:07 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236635 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/Analysis.cpp
test/CodeGen/AArch64/tail-call.ll

index ac0d40ec3a7a01f648bf798f3044b66e08d5c8e2..3224fac25cb4125bc42a9837f5a3a80a9e3ebd85 100644 (file)
@@ -295,9 +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();
-      assert(ValLoc.size() >= InsertLoc.size() && "extracting too deeply");
-      if (std::equal(InsertLoc.begin(), InsertLoc.end(),
-                     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.
index 700eec7763610e2ae5f5b09ddcec892359e57fd3..e5766154bb46fe462b8107ee8a98277f1d9f53c5 100644 (file)
@@ -122,3 +122,22 @@ define { [3 x float] } @test_add_elem() {
   %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
+}