[polly] r240518 - Add support for srem instruction
Tobias Grosser
tobias at grosser.es
Tue Jun 23 21:13:30 PDT 2015
Author: grosser
Date: Tue Jun 23 23:13:29 2015
New Revision: 240518
URL: http://llvm.org/viewvc/llvm-project?rev=240518&view=rev
Log:
Add support for srem instruction
Remainder operations with constant divisor can be modeled as quasi-affine
expression. This patch adds support for detecting and modeling them. We also
add a test that ensures they are correctly code generated.
This patch was extracted from a larger patch contributed by Johannes Doerfert
in http://reviews.llvm.org/D5293
Added:
polly/trunk/test/Isl/CodeGen/srem-in-other-bb.ll
polly/trunk/test/ScopDetect/srem_with_parametric_divisor.ll
polly/trunk/test/ScopInfo/NonAffine/non_affine_but_srem.ll
Modified:
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/Support/SCEVValidator.cpp
polly/trunk/test/ScopInfo/reduction_alternating_base.ll
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=240518&r1=240517&r2=240518&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Tue Jun 23 23:13:29 2015
@@ -105,6 +105,7 @@ private:
__isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
__isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
__isl_give isl_pw_aff *visitSDivInstruction(Instruction *SDiv);
+ __isl_give isl_pw_aff *visitSRemInstruction(Instruction *SDiv);
friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
};
@@ -283,11 +284,29 @@ __isl_give isl_pw_aff *SCEVAffinator::vi
return isl_pw_aff_tdiv_q(DividendPWA, DivisorPWA);
}
+__isl_give isl_pw_aff *SCEVAffinator::visitSRemInstruction(Instruction *SRem) {
+ assert(SRem->getOpcode() == Instruction::SRem && "Assumed SRem instruction!");
+ auto *SE = S->getSE();
+
+ auto *Divisor = dyn_cast<ConstantInt>(SRem->getOperand(1));
+ assert(Divisor && "SRem is no parameter but has a non-constant RHS.");
+ auto *DivisorVal = isl_valFromAPInt(Ctx, Divisor->getValue(),
+ /* isSigned */ true);
+
+ auto *Dividend = SRem->getOperand(0);
+ auto *DividendSCEV = SE->getSCEV(Dividend);
+ auto *DividendPWA = visit(DividendSCEV);
+
+ return isl_pw_aff_mod_val(DividendPWA, isl_val_abs(DivisorVal));
+}
+
__isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
if (Instruction *I = dyn_cast<Instruction>(Expr->getValue())) {
switch (I->getOpcode()) {
case Instruction::SDiv:
return visitSDivInstruction(I);
+ case Instruction::SRem:
+ return visitSRemInstruction(I);
default:
break; // Fall through.
}
Modified: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=240518&r1=240517&r2=240518&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Tue Jun 23 23:13:29 2015
@@ -349,6 +349,20 @@ public:
return visit(DividendSCEV);
}
+ ValidatorResult visitSRemInstruction(Instruction *SRem, const SCEV *S) {
+ assert(SRem->getOpcode() == Instruction::SRem &&
+ "Assumed SRem instruction!");
+
+ auto *Divisor = SRem->getOperand(1);
+ auto *CI = dyn_cast<ConstantInt>(Divisor);
+ if (!CI)
+ return visitGenericInst(SRem, S);
+
+ auto *Dividend = SRem->getOperand(0);
+ auto *DividendSCEV = SE.getSCEV(Dividend);
+ return visit(DividendSCEV);
+ }
+
ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
Value *V = Expr->getValue();
@@ -371,6 +385,8 @@ public:
switch (I->getOpcode()) {
case Instruction::SDiv:
return visitSDivInstruction(I, Expr);
+ case Instruction::SRem:
+ return visitSRemInstruction(I, Expr);
default:
return visitGenericInst(I, Expr);
}
Added: polly/trunk/test/Isl/CodeGen/srem-in-other-bb.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/srem-in-other-bb.ll?rev=240518&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/srem-in-other-bb.ll (added)
+++ polly/trunk/test/Isl/CodeGen/srem-in-other-bb.ll Tue Jun 23 23:13:29 2015
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-codegen -S -polly-no-early-exit < %s | FileCheck %s
+;
+; void pos(float *A, long n) {
+; for (long i = 0; i < 100; i++)
+; A[n % 42] += 1;
+; }
+;
+; CHECK: polly.stmt.bb3:
+; CHECK: %p_tmp.moved.to.bb3 = srem i64 %n, 42
+; CHECK: %p_tmp3 = getelementptr inbounds float, float* %A, i64 %p_tmp.moved.to.bb3
+
+define void @pos(float* %A, i64 %n) {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb6, %bb
+ %i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
+ %exitcond = icmp ne i64 %i.0, 100
+ br i1 %exitcond, label %bb2, label %bb8
+
+bb2: ; preds = %bb1
+ %tmp = srem i64 %n, 42
+ br label %bb3
+
+bb3:
+ %tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
+ %tmp4 = load float, float* %tmp3, align 4
+ %tmp5 = fadd float %tmp4, 1.000000e+00
+ store float %tmp5, float* %tmp3, align 4
+ br label %bb6
+
+bb6: ; preds = %bb2
+ %tmp7 = add nsw i64 %i.0, 1
+ br label %bb1
+
+bb8: ; preds = %bb1
+ ret void
+}
Added: polly/trunk/test/ScopDetect/srem_with_parametric_divisor.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/srem_with_parametric_divisor.ll?rev=240518&view=auto
==============================================================================
--- polly/trunk/test/ScopDetect/srem_with_parametric_divisor.ll (added)
+++ polly/trunk/test/ScopDetect/srem_with_parametric_divisor.ll Tue Jun 23 23:13:29 2015
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: Valid Region for Scop:
+;
+; void foo(float *A, long n, long p) {
+; for (long i = 0; i < 100; i++)
+; A[n % p] += 1;
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo(float* %A, i64 %n, i64 %p) {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb6, %bb
+ %i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
+ %exitcond = icmp ne i64 %i.0, 100
+ br i1 %exitcond, label %bb2, label %bb8
+
+bb2: ; preds = %bb1
+ %tmp = srem i64 %n, %p
+ %tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
+ %tmp4 = load float, float* %tmp3, align 4
+ %tmp5 = fadd float %tmp4, 1.000000e+00
+ store float %tmp5, float* %tmp3, align 4
+ br label %bb6
+
+bb6: ; preds = %bb2
+ %tmp7 = add nsw i64 %i.0, 1
+ br label %bb1
+
+bb8: ; preds = %bb1
+ ret void
+}
Added: polly/trunk/test/ScopInfo/NonAffine/non_affine_but_srem.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/NonAffine/non_affine_but_srem.ll?rev=240518&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/NonAffine/non_affine_but_srem.ll (added)
+++ polly/trunk/test/ScopInfo/NonAffine/non_affine_but_srem.ll Tue Jun 23 23:13:29 2015
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; void pos(float *A, long n) {
+; for (long i = 0; i < 100; i++)
+; A[n % 42] += 1;
+; }
+;
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] :
+; CHECK: exists (e0 = floor((-n + o0)/42):
+; CHECK: 42e0 = -n + o0 and o0 <= 41 and o0 >= 0) };
+; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] :
+; CHECK: exists (e0 = floor((-n + o0)/42):
+; CHECK: 42e0 = -n + o0 and o0 <= 41 and o0 >= 0) };
+;
+; void neg(float *A, long n) {
+; for (long i = 0; i < 100; i++)
+; A[n % (-42)] += 1;
+; }
+;
+; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] :
+; CHECK: exists (e0 = floor((-n + o0)/42):
+; CHECK: 42e0 = -n + o0 and o0 <= 41 and o0 >= 0) };
+; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK: [n] -> { Stmt_bb2[i0] -> MemRef_A[o0] :
+; CHECK: exists (e0 = floor((-n + o0)/42):
+; CHECK: 42e0 = -n + o0 and o0 <= 41 and o0 >= 0) };
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @pos(float* %A, i64 %n) {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb6, %bb
+ %i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
+ %exitcond = icmp ne i64 %i.0, 100
+ br i1 %exitcond, label %bb2, label %bb8
+
+bb2: ; preds = %bb1
+ %tmp = srem i64 %n, 42
+ %tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
+ %tmp4 = load float, float* %tmp3, align 4
+ %tmp5 = fadd float %tmp4, 1.000000e+00
+ store float %tmp5, float* %tmp3, align 4
+ br label %bb6
+
+bb6: ; preds = %bb2
+ %tmp7 = add nsw i64 %i.0, 1
+ br label %bb1
+
+bb8: ; preds = %bb1
+ ret void
+}
+
+define void @neg(float* %A, i64 %n) {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb6, %bb
+ %i.0 = phi i64 [ 0, %bb ], [ %tmp7, %bb6 ]
+ %exitcond = icmp ne i64 %i.0, 100
+ br i1 %exitcond, label %bb2, label %bb8
+
+bb2: ; preds = %bb1
+ %tmp = srem i64 %n, -42
+ %tmp3 = getelementptr inbounds float, float* %A, i64 %tmp
+ %tmp4 = load float, float* %tmp3, align 4
+ %tmp5 = fadd float %tmp4, 1.000000e+00
+ store float %tmp5, float* %tmp3, align 4
+ br label %bb6
+
+bb6: ; preds = %bb2
+ %tmp7 = add nsw i64 %i.0, 1
+ br label %bb1
+
+bb8: ; preds = %bb1
+ ret void
+}
Modified: polly/trunk/test/ScopInfo/reduction_alternating_base.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/reduction_alternating_base.ll?rev=240518&r1=240517&r2=240518&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/reduction_alternating_base.ll (original)
+++ polly/trunk/test/ScopInfo/reduction_alternating_base.ll Tue Jun 23 23:13:29 2015
@@ -1,15 +1,16 @@
; RUN: opt %loadPolly -polly-detect-unprofitable -polly-scops -analyze < %s | FileCheck %s
;
-; FIXME: We cannot detect this SCoP yet but as soon as we can we should check
-; that the reduction is detected!
-;
-; CHECK-NOT: Schedule
;
; void f(int *A) {
; for (int i = 0; i < 1024; i++)
; A[i % 2] += i;
; }
;
+; Verify that we detect the reduction on A
+;
+; CHECK: ReadAccess := [Reduction Type: +] [Scalar: 0]
+; CHECK: MustWriteAccess := [Reduction Type: +] [Scalar: 0]
+;
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
define void @f(i32* %A) {
More information about the llvm-commits
mailing list