Skip to content

Commit

Permalink
Merge pull request #8624 from JuliaLang/jcb/cfsimd
Browse files Browse the repository at this point in the history
Reject `@simd` loops with break / continue / `@goto` in inner loop body
  • Loading branch information
jakebolewski committed Oct 14, 2014
2 parents 821b6c5 + 797fd7b commit 63ecbcb
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Library improvements
* New `ordschur` and `ordschur!` functions for sorting a schur factorization by the eigenvalues.

* `deepcopy` recurses through immutable types and makes copies of their mutable fields ([#8560]).

* `@simd` now rejects invalid control flow (`@goto` / break / continue) in the inner loop body at compile time ([#8624]).

* Givens type doesn't have a size anymore and is no longer a subtype of AbstractMatrix ([#8660])

Expand Down
16 changes: 16 additions & 0 deletions base/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,26 @@ function parse_iteration_space(x)
x.args # symbol, range
end

# reject invalid control flow statements in @simd loop body
function check_body!(x::Expr)
if x.head === :break || x.head == :continue
throw(SimdError("$(x.head) is not allowed inside a @simd loop body"))
elseif x.head === :macrocall && x.args[1] === symbol("@goto")
throw(SimdError("$(x.args[1]) is not allowed inside a @simd loop body"))
end
for arg in x.args
check_body!(arg)
end
return true
end
check_body!(x::QuoteNode) = check_body!(x.value)
check_body!(x) = true

# Compile Expr x in context of @simd.
function compile(x)
(isa(x, Expr) && x.head == :for) || throw(SimdError("for loop expected"))
length(x.args) == 2 || throw(SimdError("1D for loop expected"))
check_body!(x)

var,range = parse_iteration_space(x.args[1])
r = gensym("r") # Range value
Expand Down
23 changes: 23 additions & 0 deletions test/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,26 @@ let j=4
end
@test !simd_loop_local_present
end

import Base.SimdLoop.SimdError

# Test that @simd rejects inner loop body with invalid control flow statements
# issue #8613
@test_throws SimdError eval(:(begin
@simd for x = 1:10
x == 1 && break
end
end))

@test_throws SimdError eval(:(begin
@simd for x = 1:10
x < 5 && continue
end
end))

@test_throws SimdError eval(:(begin
@simd for x = 1:10
x == 1 || @goto exit_loop
end
@label exit_loop
end))

0 comments on commit 63ecbcb

Please sign in to comment.