[PATCH] D24256: [InstCombine][sse4a] Fix assertion failure caused by unsafe dyn_casts on the operands of extrq/extrqi intrinsic calls.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 6 07:57:23 PDT 2016


andreadb created this revision.
andreadb added reviewers: RKSimon, majnemer.
andreadb added a subscriber: llvm-commits.

This patch fixes an assertion failure caused by unsafe dynamic casts on the constant operands of sse4a intrinsic calls to extrq/extrqi.

The combine logic that simplifies sse4a extrq/extrqi intrinsic calls currently checks if the input operands are constants. Internally, the logic relies on unsafe `dyn_casts` on the values returned by calls to method Constant::getAggregateElement. 
However, method 'getAggregateElement ' may return null if the constant element cannot be retrieved. So all the `dyn_cast` can potentially fail. This is what happens for example if a constexpr values is passed in input to the extrq/extrqi intrinsic calls.

I have added two test cases that fail with the following assertion failure:

include/llvm/Support/Casting.h:95: static bool
llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = llvm::ConstantInt; From =
llvm::Constant]: Assertion `Val && "isa<> used on a null pointer"' failed

This patch fixes the problem by using a `dyn_cast_or_null` (instead of a simple `dyn_cast` on the result of calls to Constant::getAggregateElement.

Please let me know if okay to commit.

Thanks,
Andrea

https://reviews.llvm.org/D24256

Files:
  lib/Transforms/InstCombine/InstCombineCalls.cpp
  test/Transforms/InstCombine/x86-sse4a.ll

Index: test/Transforms/InstCombine/x86-sse4a.ll
===================================================================
--- test/Transforms/InstCombine/x86-sse4a.ll
+++ test/Transforms/InstCombine/x86-sse4a.ll
@@ -55,6 +55,15 @@
   ret <2 x i64> %1
 }
 
+define <2 x i64> @test_extrq_call_constexpr(<2 x i64> %x) {
+; CHECK-LABEL: @test_extrq_call_constexpr(
+; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> %x, <16 x i8> bitcast (<2 x i64> <i64 0, i64 undef> to <16 x i8>))
+; CHECK-NEXT:    ret <2 x i64> [[TMP1]]
+;
+  %1 = call <2 x i64> @llvm.x86.sse4a.extrq(<2 x i64> %x, <16 x i8> bitcast (<2 x i64> <i64 0, i64 undef> to <16 x i8>))
+  ret <2 x i64> %1
+}
+
 ;
 ; EXTRQI
 ;
@@ -122,6 +131,14 @@
   ret <2 x i64> %1
 }
 
+define <2 x i64> @test_extrqi_call_constexpr() {
+; CHECK-LABEL: @test_extrqi_call_constexpr(
+; CHECK-NEXT:    ret <2 x i64> bitcast (<16 x i8> <i8 extractelement (<16 x i8> trunc (<16 x i16> bitcast (<4 x i64> <i64 0, i64 undef, i64 2, i64 undef> to <16 x i16>) to <16 x i8>), i32 2), i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef> to <2 x i64>)
+;
+  %1 = tail call <2 x i64> @llvm.x86.sse4a.extrqi(<2 x i64> bitcast (<16 x i8> trunc (<16 x i16> bitcast (<4 x i64> <i64 0, i64 undef, i64 2, i64 undef> to <16 x i16>) to <16 x i8>) to <2 x i64>), i8 8, i8 16)
+  ret <2 x i64> %1
+}
+
 ;
 ; INSERTQ
 ;
Index: lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -584,7 +584,7 @@
   // See if we're dealing with constant values.
   Constant *C0 = dyn_cast<Constant>(Op0);
   ConstantInt *CI0 =
-      C0 ? dyn_cast<ConstantInt>(C0->getAggregateElement((unsigned)0))
+      C0 ? dyn_cast_or_null<ConstantInt>(C0->getAggregateElement((unsigned)0))
          : nullptr;
 
   // Attempt to constant fold.
@@ -1856,10 +1856,10 @@
     // See if we're dealing with constant values.
     Constant *C1 = dyn_cast<Constant>(Op1);
     ConstantInt *CILength =
-        C1 ? dyn_cast<ConstantInt>(C1->getAggregateElement((unsigned)0))
+        C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)0))
            : nullptr;
     ConstantInt *CIIndex =
-        C1 ? dyn_cast<ConstantInt>(C1->getAggregateElement((unsigned)1))
+        C1 ? dyn_cast_or_null<ConstantInt>(C1->getAggregateElement((unsigned)1))
            : nullptr;
 
     // Attempt to simplify to a constant, shuffle vector or EXTRQI call.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24256.70396.patch
Type: text/x-patch
Size: 2614 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160906/1e129595/attachment.bin>


More information about the llvm-commits mailing list