diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2014-09-17 04:16:35 +0000 | 
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2014-09-17 04:16:35 +0000 | 
| commit | b435a4214e5920e56dd2e9fb5fb29bb2d4e98fab (patch) | |
| tree | ded4fd97a32f32c0f9007df848fb85b2d56b2e20 | |
| parent | 29298664d907ad227991075add40b46893867930 (diff) | |
| download | bcm5719-llvm-b435a4214e5920e56dd2e9fb5fb29bb2d4e98fab.tar.gz bcm5719-llvm-b435a4214e5920e56dd2e9fb5fb29bb2d4e98fab.zip  | |
InstSimplify: Don't allow (x srem y) urem y -> x srem y
Let's consider the case where:
%x i16 = 32768
%y i16 = 384
%x srem %y = 65408
(%x srem %y) urem %y = 128
llvm-svn: 217939
| -rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/rem.ll | 23 | 
2 files changed, 26 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 039d8286ecb..f2f67067d15 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1171,10 +1171,12 @@ static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1,    if (Op0 == Op1)      return Constant::getNullValue(Op0->getType()); -  // ((X % Y) % Y) -> (X % Y) -  if (match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) { +  // (X % Y) % Y -> X % Y +  if ((Opcode == Instruction::SRem && +       match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) || +      (Opcode == Instruction::URem && +       match(Op0, m_URem(m_Value(), m_Specific(Op1)))))      return Op0; -  }    // 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. diff --git a/llvm/test/Transforms/InstSimplify/rem.ll b/llvm/test/Transforms/InstSimplify/rem.ll index b757ccd6e4d..f5ea45107e2 100644 --- a/llvm/test/Transforms/InstSimplify/rem.ll +++ b/llvm/test/Transforms/InstSimplify/rem.ll @@ -16,11 +16,30 @@ define i32 @select2(i32 %x, i1 %b) {  ; CHECK: ret i32 0  } -define i32 @select3(i32 %x, i32 %n) { -; CHECK-LABEL: @select3( +define i32 @rem1(i32 %x, i32 %n) { +; CHECK-LABEL: @rem1(  ; CHECK-NEXT: %mod = srem i32 %x, %n  ; CHECK-NEXT: ret i32 %mod   %mod = srem i32 %x, %n   %mod1 = srem i32 %mod, %n   ret i32 %mod1  } + +define i32 @rem2(i32 %x, i32 %n) { +; CHECK-LABEL: @rem2( +; CHECK-NEXT: %mod = urem i32 %x, %n +; CHECK-NEXT: ret i32 %mod + %mod = urem i32 %x, %n + %mod1 = urem i32 %mod, %n + ret i32 %mod1 +} + +define i32 @rem3(i32 %x, i32 %n) { +; CHECK-LABEL: @rem3( +; CHECK-NEXT: %[[srem:.*]] = srem i32 %x, %n +; CHECK-NEXT: %[[urem:.*]] = urem i32 %[[srem]], %n +; CHECK-NEXT: ret i32 %[[urem]] + %mod = srem i32 %x, %n + %mod1 = urem i32 %mod, %n + ret i32 %mod1 +}  | 

