Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -4095,6 +4095,7 @@ case Instruction::Sub: case Instruction::Mul: case Instruction::UDiv: + case Instruction::URem: case Instruction::And: case Instruction::Or: case Instruction::AShr: @@ -5417,6 +5418,13 @@ } case Instruction::UDiv: return getUDivExpr(getSCEV(BO->LHS), getSCEV(BO->RHS)); + case Instruction::URem: { + const SCEV *LSCEV = getSCEV(BO->LHS); + const SCEV *RSCEV = getSCEV(BO->RHS); + const SCEV *UDiv = getUDivExpr(LSCEV, RSCEV); + const SCEV *Mult = getMulExpr(UDiv, RSCEV, SCEV::FlagNUW); + return getMinusSCEV(LSCEV, Mult, SCEV::FlagNUW); + } case Instruction::Sub: { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap; if (BO->Op) Index: test/Analysis/ScalarEvolution/flattened.ll =================================================================== --- /dev/null +++ test/Analysis/ScalarEvolution/flattened.ll @@ -0,0 +1,22 @@ +; RUN: opt < %s -scalar-evolution -analyze | tee /dev/fd/2 | FileCheck %s + + +define void @foo([7 x i8]* %a) { +entry: + br label %bb + +bb: + %idx = phi i64 [ 0, %entry ], [ %idx.incr, %bb ] + %i = udiv i64 %idx, 7 + %j = urem i64 %idx, 7 + %a.ptr = getelementptr [7 x i8], [7 x i8]* %a, i64 %i, i64 %j +; CHECK: %a.ptr +; CHECK: --> {%a,+,1}<%bb> + %val = load i8, i8* %a.ptr + %idx.incr = add i64 %idx, 1 + %test = icmp ne i64 %idx.incr, 35 + br i1 %test, label %bb, label %exit + +exit: + ret void +} Index: test/Analysis/ScalarEvolution/urem-0.ll =================================================================== --- /dev/null +++ test/Analysis/ScalarEvolution/urem-0.ll @@ -0,0 +1,8 @@ +; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s + +; CHECK: --> ((-27 * (%a /u 27)) + %a) + +define i8 @foo(i8 %a) { + %t0 = urem i8 %a, 27 + ret i8 %t0 +}