From 666ce57961706b21c46bc6f3a113b1a707baae8b Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Mon, 30 Apr 2018 06:36:15 -0400
Subject: [PATCH] feat(opencl): if statements with empty blocks now compile as
 well as comparisons outside of conditio

---
 CHANGELOG.md                                  |  4 +-
 .../aparapi/internal/writer/BlockWriter.java  |  6 ++-
 .../aparapi/codegen/test/ContinueTorture.java |  1 -
 .../aparapi/codegen/test/EmptyIfBlock.java    | 26 ++++++++++
 .../codegen/test/EmptyIfBlockTest.java        | 51 ++++++++++++++++++
 .../aparapi/codegen/test/PreDecrement.java    | 23 ++++++++
 .../codegen/test/PreDecrementTest.java        | 52 +++++++++++++++++++
 .../com/aparapi/runtime/PreDecrementTest.java | 36 +++++++++++++
 8 files changed, 195 insertions(+), 4 deletions(-)
 create mode 100644 src/test/java/com/aparapi/codegen/test/EmptyIfBlock.java
 create mode 100644 src/test/java/com/aparapi/codegen/test/EmptyIfBlockTest.java
 create mode 100644 src/test/java/com/aparapi/codegen/test/PreDecrement.java
 create mode 100644 src/test/java/com/aparapi/codegen/test/PreDecrementTest.java
 create mode 100644 src/test/java/com/aparapi/runtime/PreDecrementTest.java

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e1b9902..1708c590 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,8 @@
 # Aparapi Changelog
 
-## 1.9.1
+## 1.10.0
+
+* If statements with empty blocks and comparisons outside of if or while statements now compile and run on the GPU.
 
 ## 1.9.0
 
diff --git a/src/main/java/com/aparapi/internal/writer/BlockWriter.java b/src/main/java/com/aparapi/internal/writer/BlockWriter.java
index 8e8ed04b..22789c60 100644
--- a/src/main/java/com/aparapi/internal/writer/BlockWriter.java
+++ b/src/main/java/com/aparapi/internal/writer/BlockWriter.java
@@ -745,8 +745,10 @@ public abstract class BlockWriter{
       } else if (_instruction.getByteCode().equals(ByteCode.NONE)) {
          // we are done
       } else if (_instruction instanceof Branch) {
-         throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(),
-               ((Branch) _instruction).getTarget().getThisPC()));
+          if(_instruction instanceof ConditionalBranch16)
+            writeConditionalBranch16((ConditionalBranch16) _instruction, true);
+          else
+            throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(), ((Branch) _instruction).getTarget().getThisPC()));
       } else if (_instruction instanceof I_POP) {
          //POP discarded void call return?
          writeInstruction(_instruction.getFirstChild());
diff --git a/src/test/java/com/aparapi/codegen/test/ContinueTorture.java b/src/test/java/com/aparapi/codegen/test/ContinueTorture.java
index b172b17c..36333217 100644
--- a/src/test/java/com/aparapi/codegen/test/ContinueTorture.java
+++ b/src/test/java/com/aparapi/codegen/test/ContinueTorture.java
@@ -35,7 +35,6 @@ public class ContinueTorture {
     public void run() {
         int idx = myId;
         while (--idx > 0) {
-
             if (myId == 0) {
                 continue;
             }
diff --git a/src/test/java/com/aparapi/codegen/test/EmptyIfBlock.java b/src/test/java/com/aparapi/codegen/test/EmptyIfBlock.java
new file mode 100644
index 00000000..b73fb961
--- /dev/null
+++ b/src/test/java/com/aparapi/codegen/test/EmptyIfBlock.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.codegen.test;
+
+public class EmptyIfBlock {
+
+    public void run() {
+        int idx = 34;
+        if(idx < 5) {
+        }
+    }
+}
+/**{Throws{ClassParseException}Throws}**/
diff --git a/src/test/java/com/aparapi/codegen/test/EmptyIfBlockTest.java b/src/test/java/com/aparapi/codegen/test/EmptyIfBlockTest.java
new file mode 100644
index 00000000..ae8efe70
--- /dev/null
+++ b/src/test/java/com/aparapi/codegen/test/EmptyIfBlockTest.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.codegen.test;
+
+import org.junit.Test;
+
+public class EmptyIfBlockTest extends com.aparapi.codegen.CodeGenJUnitBase {
+    private static final String[] expectedOpenCL = {"typedef struct This_s{\n" +
+        "   int passid;\n" +
+        "}This;\n" +
+        "int get_pass_id(This *this){\n" +
+        "   return this->passid;\n" +
+        "}\n" +
+        "__kernel void run(\n" +
+        "   int passid\n" +
+        "){\n" +
+        "   This thisStruct;\n" +
+        "   This* this=&thisStruct;\n" +
+        "   this->passid = passid;\n" +
+        "   {\n" +
+        "      int idx = 34;\n" +
+        "      idx<5;\n" +
+        "      return;\n" +
+        "   }\n" +
+        "}\n" +
+        "\n"};
+    private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = null;
+
+    @Test
+    public void EmptyIfBlockTest() {
+        test(EmptyIfBlock.class, expectedException, expectedOpenCL);
+    }
+
+    @Test
+    public void EmptyIfBlockTestWorksWithCaching() {
+        test(EmptyIfBlock.class, expectedException, expectedOpenCL);
+    }
+}
diff --git a/src/test/java/com/aparapi/codegen/test/PreDecrement.java b/src/test/java/com/aparapi/codegen/test/PreDecrement.java
new file mode 100644
index 00000000..4a26d538
--- /dev/null
+++ b/src/test/java/com/aparapi/codegen/test/PreDecrement.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.codegen.test;
+
+public class PreDecrement {
+    public void run() {
+        int i = 123;
+        boolean result = --i < 123;
+    }
+}
diff --git a/src/test/java/com/aparapi/codegen/test/PreDecrementTest.java b/src/test/java/com/aparapi/codegen/test/PreDecrementTest.java
new file mode 100644
index 00000000..e42f7625
--- /dev/null
+++ b/src/test/java/com/aparapi/codegen/test/PreDecrementTest.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.codegen.test;
+
+import org.junit.Test;
+
+public class PreDecrementTest extends com.aparapi.codegen.CodeGenJUnitBase {
+
+    private static final String[] expectedOpenCL = {"typedef struct This_s{\n" +
+        "   int passid;\n" +
+        "}This;\n" +
+        "int get_pass_id(This *this){\n" +
+        "   return this->passid;\n" +
+        "}\n" +
+        "__kernel void run(\n" +
+        "   int passid\n" +
+        "){\n" +
+        "   This thisStruct;\n" +
+        "   This* this=&thisStruct;\n" +
+        "   this->passid = passid;\n" +
+        "   {\n" +
+        "      int i = 123;\n" +
+        "      i--;\n" +
+        "      char result = (i<123)?1:0;\n" +
+        "      return;\n" +
+        "   }\n" +
+        "}\n" +
+        "\n"};
+    private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = null;
+
+    @Test
+    public void PreDecPostIncTest() { test(PreDecrement.class, expectedException, expectedOpenCL);
+    }
+
+    @Test
+    public void PreDecPostIncTestWorksWithCaching() {
+        test(PreDecrement.class, expectedException, expectedOpenCL);
+    }
+}
diff --git a/src/test/java/com/aparapi/runtime/PreDecrementTest.java b/src/test/java/com/aparapi/runtime/PreDecrementTest.java
new file mode 100644
index 00000000..648ce40c
--- /dev/null
+++ b/src/test/java/com/aparapi/runtime/PreDecrementTest.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2016 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.aparapi.runtime;
+
+import com.aparapi.Kernel;
+import org.junit.Test;
+
+
+public class PreDecrementTest {
+    @Test
+    public void test() {
+        PreDecrement kernel = new PreDecrement();
+        kernel.execute(1);
+    }
+
+    public class PreDecrement extends Kernel {
+        public void run() {
+            int idx = 34;
+            if(idx < 5) {
+            }
+        }
+    }
+}
-- 
GitLab