summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp7
-rw-r--r--llvm/test/Transforms/InstSimplify/rem.ll16
2 files changed, 11 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 6c6b1cfe720..245133fb912 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1040,6 +1040,13 @@ static Value *simplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,
match(Op0, m_URem(m_Value(), m_Specific(Op1)))))
return Op0;
+ // (X << Y) % X -> 0
+ if ((Opcode == Instruction::SRem &&
+ match(Op0, m_NSWShl(m_Specific(Op1), m_Value()))) ||
+ (Opcode == Instruction::URem &&
+ match(Op0, m_NUWShl(m_Specific(Op1), m_Value()))))
+ return Constant::getNullValue(Op0->getType());
+
// If the operation is with the result of a select instruction, check whether
// operating on either branch of the select always yields the same value.
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll
index d949d6ea353..a015d4c43e0 100644
--- a/llvm/test/Transforms/InstSimplify/rem.ll
+++ b/llvm/test/Transforms/InstSimplify/rem.ll
@@ -189,9 +189,7 @@ define i32 @rem4() {
define i32 @rem5(i32 %x, i32 %y) {
; CHECK-LABEL: @rem5(
-; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[MOD:%.*]] = srem i32 [[SHL]], [[X]]
-; CHECK-NEXT: ret i32 [[MOD]]
+; CHECK-NEXT: ret i32 0
;
%shl = shl nsw i32 %x, %y
%mod = srem i32 %shl, %x
@@ -200,9 +198,7 @@ define i32 @rem5(i32 %x, i32 %y) {
define <2 x i32> @rem6(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @rem6(
-; CHECK-NEXT: [[SHL:%.*]] = shl nsw <2 x i32> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[MOD:%.*]] = srem <2 x i32> [[SHL]], [[X]]
-; CHECK-NEXT: ret <2 x i32> [[MOD]]
+; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
%shl = shl nsw <2 x i32> %x, %y
%mod = srem <2 x i32> %shl, %x
@@ -224,9 +220,7 @@ define i32 @rem7(i32 %x, i32 %y) {
define i32 @rem8(i32 %x, i32 %y) {
; CHECK-LABEL: @rem8(
-; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[MOD:%.*]] = urem i32 [[SHL]], [[X]]
-; CHECK-NEXT: ret i32 [[MOD]]
+; CHECK-NEXT: ret i32 0
;
%shl = shl nuw i32 %x, %y
%mod = urem i32 %shl, %x
@@ -235,9 +229,7 @@ define i32 @rem8(i32 %x, i32 %y) {
define <2 x i32> @rem9(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @rem9(
-; CHECK-NEXT: [[SHL:%.*]] = shl nuw <2 x i32> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[MOD:%.*]] = urem <2 x i32> [[SHL]], [[X]]
-; CHECK-NEXT: ret <2 x i32> [[MOD]]
+; CHECK-NEXT: ret <2 x i32> zeroinitializer
;
%shl = shl nuw <2 x i32> %x, %y
%mod = urem <2 x i32> %shl, %x
OpenPOWER on IntegriCloud