aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Neuschäfer <j.neuschaefer@gmx.net>2012-08-19 16:52:16 +0200
committerPekka Enberg <penberg@kernel.org>2012-08-19 18:10:34 +0300
commite03a53b13e76c8049406eca28c843da33d3e394d (patch)
tree1fa611f4ceb1e99ddb09ecc6b149a45619c970e4
parent33844e787a0ed80d04b2917042fec50ccf4c91dd (diff)
downloadsparse-e03a53b13e76c8049406eca28c843da33d3e394d.tar.gz
sparse, llvm: convert the condition of branch/select to bool
LLVM expects the first argument of "br" and "select" to be of type i1, so add an "icmp ne <srcty> %src, 0" for other types. Cc: Christopher Li <sparse@chrisli.org> Cc: Jeff Garzik <jgarzik@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net> Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r--sparse-llvm.c13
-rw-r--r--validation/backend/int-cond.c30
2 files changed, 41 insertions, 2 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 213d42d3..e4929e9b 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -650,10 +650,19 @@ static void output_op_store(struct function *fn, struct instruction *insn)
insn->target->priv = target;
}
+static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value)
+{
+ if (LLVMTypeOf(value) != LLVMInt1Type())
+ value = LLVMBuildIsNotNull(fn->builder, value, "cond");
+
+ return value;
+}
+
static void output_op_br(struct function *fn, struct instruction *br)
{
if (br->cond) {
- LLVMValueRef cond = pseudo_to_value(fn, br, br->cond);
+ LLVMValueRef cond = bool_value(fn,
+ pseudo_to_value(fn, br, br->cond));
LLVMBuildCondBr(fn->builder, cond,
br->bb_true->priv,
@@ -668,7 +677,7 @@ static void output_op_sel(struct function *fn, struct instruction *insn)
{
LLVMValueRef target, src1, src2, src3;
- src1 = pseudo_to_value(fn, insn, insn->src1);
+ src1 = bool_value(fn, pseudo_to_value(fn, insn, insn->src1));
src2 = pseudo_to_value(fn, insn, insn->src2);
src3 = pseudo_to_value(fn, insn, insn->src3);
diff --git a/validation/backend/int-cond.c b/validation/backend/int-cond.c
new file mode 100644
index 00000000..48b25a77
--- /dev/null
+++ b/validation/backend/int-cond.c
@@ -0,0 +1,30 @@
+static long foo(long a, long b, long c)
+{
+ return a? b:c;
+}
+
+static long foo_bool(_Bool a, long b, long c)
+{
+ return a? b:c;
+}
+
+static long bar(long a, long b, long c)
+{
+ if (a)
+ return b;
+ else
+ return b + c;
+}
+
+static long bar_bool(_Bool a, long b, long c)
+{
+ if (a)
+ return b;
+ else
+ return b + c;
+}
+
+/*
+ * check-name: Non-bool condition values in branch/select
+ * check-command: ./sparsec -c $file -o tmp.o
+ */