[DAGCombiner] Use APInt directly to detect out of range shift constants
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 27 Jul 2016 10:30:55 +0000 (10:30 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 27 Jul 2016 10:30:55 +0000 (10:30 +0000)
Using getZExtValue() will assert if the value doesn't fit into uint64_t - SHL was already doing this, I've just updated ASHR/LSHR to match

As mentioned on D22726

llvm-svn: 276855

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/shift-i128.ll

index d888676..59de12b 100644 (file)
@@ -4634,8 +4634,8 @@ SDValue DAGCombiner::visitSRA(SDNode *N) {
   // fold (sra -1, x) -> -1
   if (isAllOnesConstant(N0))
     return N0;
-  // fold (sra x, (setge c, size(x))) -> undef
-  if (N1C && N1C->getZExtValue() >= OpSizeInBits)
+  // fold (sra x, c >= size(x)) -> undef
+  if (N1C && N1C->getAPIntValue().uge(OpSizeInBits))
     return DAG.getUNDEF(VT);
   // fold (sra x, 0) -> x
   if (N1C && N1C->isNullValue())
@@ -4778,7 +4778,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
   if (isNullConstant(N0))
     return N0;
   // fold (srl x, c >= size(x)) -> undef
-  if (N1C && N1C->getZExtValue() >= OpSizeInBits)
+  if (N1C && N1C->getAPIntValue().uge(OpSizeInBits))
     return DAG.getUNDEF(VT);
   // fold (srl x, 0) -> x
   if (N1C && N1C->isNullValue())
index c4d15ae..77b526b 100644 (file)
@@ -1,9 +1,94 @@
-; RUN: llc < %s -march=x86
-; RUN: llc < %s -march=x86-64
-
-define void @t(i128 %x, i128 %a, i128* nocapture %r) nounwind {
-entry:
-       %0 = lshr i128 %x, %a
-       store i128 %0, i128* %r, align 16
-       ret void
-}
+; RUN: llc < %s -march=x86\r
+; RUN: llc < %s -march=x86-64\r
+\r
+;\r
+; Scalars\r
+;\r
+\r
+define void @test_lshr_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = lshr i128 %x, %a\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_ashr_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = ashr i128 %x, %a\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_shl_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = shl i128 %x, %a\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_lshr_i128_outofrange(i128 %x, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = lshr i128 %x, -1\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_ashr_i128_outofrange(i128 %x, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = ashr i128 %x, -1\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_shl_i128_outofrange(i128 %x, i128* nocapture %r) nounwind {\r
+entry:\r
+       %0 = shl i128 %x, -1\r
+       store i128 %0, i128* %r, align 16\r
+       ret void\r
+}\r
+\r
+;\r
+; Vectors\r
+;\r
+\r
+define void @test_lshr_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = lshr <2 x i128> %x, %a\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_ashr_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = ashr <2 x i128> %x, %a\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_shl_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = shl <2 x i128> %x, %a\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_lshr_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = lshr <2 x i128> %x, <i128 -1, i128 -1>\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_ashr_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = ashr <2 x i128> %x, <i128 -1, i128 -1>\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r
+\r
+define void @test_shl_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind {\r
+entry:\r
+       %0 = shl <2 x i128> %x, <i128 -1, i128 -1>\r
+       store <2 x i128> %0, <2 x i128>* %r, align 16\r
+       ret void\r
+}\r