draw: avoid overflows in the llvm draw loop
authorZack Rusin <zackr@vmware.com>
Mon, 24 Jun 2013 22:49:40 +0000 (18:49 -0400)
committerZack Rusin <zackr@vmware.com>
Tue, 25 Jun 2013 15:56:41 +0000 (11:56 -0400)
Before we could easily overflow if start+count>max integer. To
avoid it we can just iterate over the count. This makes sure
that we never crash, since most of the overflow conditions
is already handled.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c

index 6733e08fa4aaa952552d61520e3015a476f8242d..5373d1a0a8fa66b1cbae0eec63cbc14634ce9019 100644 (file)
@@ -720,7 +720,7 @@ generate_fetch(struct gallivm_state *gallivm,
                                      stride, buffer_size,
                                      "buffer_overflowed");
    /*
-   lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);
+   lp_build_printf(gallivm, "vbuf index = %u, stride is %u\n", index, stride);
    lp_build_print_value(gallivm, "   buffer size = ", buffer_size);
    lp_build_print_value(gallivm, "   buffer overflowed = ", buffer_overflowed);
    */
@@ -1595,6 +1595,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
    if (elts) {
       start = zero;
       end = fetch_count;
+      count = fetch_count;
    }
    else {
       end = lp_build_add(&bld, start, count);
@@ -1604,7 +1605,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
 
    fetch_max = LLVMBuildSub(builder, end, one, "fetch_max");
 
-   lp_build_loop_begin(&lp_loop, gallivm, start);
+   lp_build_loop_begin(&lp_loop, gallivm, zero);
    {
       LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS];
       LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][LP_MAX_VECTOR_WIDTH / 32] = { { 0 } };
@@ -1612,10 +1613,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
       LLVMValueRef clipmask;   /* holds the clipmask value */
       const LLVMValueRef (*ptr_aos)[TGSI_NUM_CHANNELS];
 
-      if (elts)
-         io_itr = lp_loop.counter;
-      else
-         io_itr = LLVMBuildSub(builder, lp_loop.counter, start, "");
+      io_itr = lp_loop.counter;
 
       io = LLVMBuildGEP(builder, io_ptr, &io_itr, 1, "");
 #if DEBUG_STORE
@@ -1628,6 +1626,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
             LLVMBuildAdd(builder,
                          lp_loop.counter,
                          lp_build_const_int32(gallivm, i), "");
+         true_index = LLVMBuildAdd(builder, start, true_index, "");
 
          /* make sure we're not out of bounds which can happen
           * if fetch_count % 4 != 0, because on the last iteration
@@ -1744,8 +1743,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
                      vs_info->num_outputs, vs_type,
                      have_clipdist);
    }
-
-   lp_build_loop_end_cond(&lp_loop, end, step, LLVMIntUGE);
+   lp_build_loop_end_cond(&lp_loop, count, step, LLVMIntUGE);
 
    sampler->destroy(sampler);