/// @brief Get the new version of a value.
///
/// Given an old value, we first check if a new version of this value is
- /// available in the BBMap or GlobalMap. If the value is scop constant, we
- /// assume it is a parameter and return the old value. In case it is not and
- /// the value can be recomputed using SCEV, we do so. If the value can still
- /// not be derived, this function will assert.
+ /// available in the BBMap or GlobalMap. In case it is not and the value can
+ /// be recomputed using SCEV, we do so. If we can not recompute a value
+ /// using SCEV, but we understand that the value is constant within the scop,
+ /// we return the old value. If the value can still not be derived, this
+ /// function will assert.
///
/// @param Old The old Value.
/// @param BBMap A mapping from old values to their new values
return New;
}
- // Or it is probably a scop-constant value defined as global, function
- // parameter or an instruction not within the scop.
- if (isa<GlobalValue>(Old) || isa<Argument>(Old))
- return const_cast<Value *>(Old);
-
- if (const Instruction *Inst = dyn_cast<Instruction>(Old))
- if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
- return const_cast<Value *>(Old);
-
if (Value *New = BBMap.lookup(Old))
return New;
}
}
- // Now the scalar dependence is neither available nor SCEVCodegenable, this
- // should never happen in the current code generator.
+ // A scop-constant value defined by a global or a function parameter.
+ if (isa<GlobalValue>(Old) || isa<Argument>(Old))
+ return const_cast<Value *>(Old);
+
+ // A scop-constant value defined by an instruction executed outside the scop.
+ if (const Instruction *Inst = dyn_cast<Instruction>(Old))
+ if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
+ return const_cast<Value *>(Old);
+
+ // The scalar dependence is neither available nor SCEVCodegenable.
llvm_unreachable("Unexpected scalar dependence in region!");
return nullptr;
}
--- /dev/null
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s | FileCheck %s
+
+; Test the code generation in the presence of a scalar out-of-scop value being
+; used from within the SCoP.
+
+; CHECH-LABEL: @scalar-function-argument
+; CHECK: polly.split_new_and_old
+
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @scalar-function-argument(float* %A, float %sqrinv) {
+entry:
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
+ %mul104 = fmul float 1.0, %sqrinv
+ %rp107 = getelementptr float* %A, i64 %indvar
+ store float %mul104, float* %rp107, align 4
+ %indvar.next = add nsw i64 %indvar, 1
+ %cmp = icmp slt i64 1024, %indvar.next
+ br i1 %cmp, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+; CHECH-LABEL: @scalar-outside-of-scop
+; CHECK: polly.split_new_and_old
+
+define void @scalar-outside-of-scop(float* %A) {
+entry:
+ %sqrinv = call float @getFloat()
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
+ %mul104 = fmul float 1.0, %sqrinv
+ %rp107 = getelementptr float* %A, i64 %indvar
+ store float %mul104, float* %rp107, align 4
+ %indvar.next = add nsw i64 %indvar, 1
+ %cmp = icmp slt i64 1024, %indvar.next
+ br i1 %cmp, label %for.end, label %for.body
+
+for.end:
+ ret void
+}
+
+declare float @getFloat()