From 36a9d6535767f2fa7cca74875957ed66742972bc Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Wed, 27 Jul 2016 10:30:55 +0000 Subject: [PATCH] [DAGCombiner] Use APInt directly to detect out of range shift constants 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276855 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 +- test/CodeGen/X86/shift-i128.ll | 103 ++++++++++++++++++++++++++++--- 2 files changed, 97 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d888676583f..59de12b0be9 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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()) diff --git a/test/CodeGen/X86/shift-i128.ll b/test/CodeGen/X86/shift-i128.ll index c4d15ae9053..77b526b5dc2 100644 --- a/test/CodeGen/X86/shift-i128.ll +++ b/test/CodeGen/X86/shift-i128.ll @@ -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 +; RUN: llc < %s -march=x86-64 + +; +; Scalars +; + +define void @test_lshr_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind { +entry: + %0 = lshr i128 %x, %a + store i128 %0, i128* %r, align 16 + ret void +} + +define void @test_ashr_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind { +entry: + %0 = ashr i128 %x, %a + store i128 %0, i128* %r, align 16 + ret void +} + +define void @test_shl_i128(i128 %x, i128 %a, i128* nocapture %r) nounwind { +entry: + %0 = shl i128 %x, %a + store i128 %0, i128* %r, align 16 + ret void +} + +define void @test_lshr_i128_outofrange(i128 %x, i128* nocapture %r) nounwind { +entry: + %0 = lshr i128 %x, -1 + store i128 %0, i128* %r, align 16 + ret void +} + +define void @test_ashr_i128_outofrange(i128 %x, i128* nocapture %r) nounwind { +entry: + %0 = ashr i128 %x, -1 + store i128 %0, i128* %r, align 16 + ret void +} + +define void @test_shl_i128_outofrange(i128 %x, i128* nocapture %r) nounwind { +entry: + %0 = shl i128 %x, -1 + store i128 %0, i128* %r, align 16 + ret void +} + +; +; Vectors +; + +define void @test_lshr_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = lshr <2 x i128> %x, %a + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} + +define void @test_ashr_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = ashr <2 x i128> %x, %a + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} + +define void @test_shl_v2i128(<2 x i128> %x, <2 x i128> %a, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = shl <2 x i128> %x, %a + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} + +define void @test_lshr_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = lshr <2 x i128> %x, + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} + +define void @test_ashr_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = ashr <2 x i128> %x, + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} + +define void @test_shl_v2i128_outofrange(<2 x i128> %x, <2 x i128>* nocapture %r) nounwind { +entry: + %0 = shl <2 x i128> %x, + store <2 x i128> %0, <2 x i128>* %r, align 16 + ret void +} -- 2.11.0