[PATCH] Transform OR of SELECTs to SELECT of ORs

Nick Lewycky nicholas at mxc.ca
Fri Feb 1 12:04:54 PST 2013


Muhammad Tauqir wrote:
> More descriptively, the transform is:
> (or (bool?A:B),(bool?C:D)) -->  (bool?(or A,C):(or B,D))
>
> By the time the OR is visited, both the SELECTs have been visited and not optimized and the OR itself hasn't been transformed so we do this transform in the hopes that the new ORs will be optimized.
>
> The transform is explicitly disabled for vector-selects until "codegen matures to handle them better".
>
> http://llvm-reviews.chandlerc.com/D362
>
> Files:
>    lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
>    test/Transforms/InstCombine/logical-select.ll
>
> Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> ===================================================================
> --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> @@ -2071,6 +2071,22 @@
>       return BinaryOperator::CreateOr(Inner, C1);
>     }
>
> +  // Change (or (bool?A:B),(bool?C:D)) -->  (bool?(or A,C):(or B,D))
> +  // Since this OR statement hasn't been optimized further yet, we hope
> +  // that this transformation will allow the new ORs to be optimized.
> +  {
> +    Value *X = 0;
> +    // FIXME: Disable vector-select until codegen matures to handle them better.
> +    // See test32 in test/Transforms/InstCombine/or.ll
> +    if (!I.getType()->isVectorTy())
> +      if (match(Op0, m_Select(m_Value(X), m_Value(A), m_Value(B)))&&
> +          match(Op1, m_Select(m_Value(X), m_Value(C), m_Value(D)))) {

You also need to check that the two selects only have one use (the 'or') 
otherwise this transform may bloat the code as we end up computing all 
of "bool?A:B", "bool?C:D" and "bool?(or A,C):(or B,D)".

"Op0->hasOneUse() && Op1->hasOneUse()" should do it.

Nick

> +        Value *orTrue = Builder->CreateOr(A, C);
> +        Value *orFalse = Builder->CreateOr(B, D);
> +        return SelectInst::Create(X, orTrue, orFalse);
> +      }
> +  }
> +
>     return Changed ?&I : 0;
>   }
>
> Index: test/Transforms/InstCombine/logical-select.ll
> ===================================================================
> --- test/Transforms/InstCombine/logical-select.ll
> +++ test/Transforms/InstCombine/logical-select.ll
> @@ -10,10 +10,8 @@
>     %j = or i32 %g, %i
>     ret i32 %j
>   ; CHECK: %e = icmp slt i32 %a, %b
> -; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
> -; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
> -; CHECK-NEXT: %j = or i32 %g, %i
> -; CHECK-NEXT: ret i32 %j
> +; CHECK-NEXT: [[result:%.*]] = select i1 %e, i32 %c, i32 %d
> +; CHECK-NEXT: ret i32 [[result]]
>   }
>   define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
>     %e = icmp slt i32 %a, %b
> @@ -24,10 +22,8 @@
>     %j = or i32 %i, %g
>     ret i32 %j
>   ; CHECK: %e = icmp slt i32 %a, %b
> -; CHECK-NEXT: %g = select i1 %e, i32 %c, i32 0
> -; CHECK-NEXT: %i = select i1 %e, i32 0, i32 %d
> -; CHECK-NEXT: %j = or i32 %i, %g
> -; CHECK-NEXT: ret i32 %j
> +; CHECK-NEXT: [[result:%.*]] = select i1 %e, i32 %c, i32 %d
> +; CHECK-NEXT: ret i32 [[result]]
>   }
>
>   define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
> @@ -40,10 +36,8 @@
>     %3 = or i32 %1, %2
>     ret i32 %3
>   ; CHECK: %0 = icmp slt i32 %a, %b
> -; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
> -; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
> -; CHECK-NEXT: %3 = or i32 %1, %2
> -; CHECK-NEXT: ret i32 %3
> +; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
> +; CHECK-NEXT: ret i32 [[result]]
>   }
>   define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
>   entry:
> @@ -55,10 +49,8 @@
>     %3 = or i32 %1, %2
>     ret i32 %3
>   ; CHECK: %0 = icmp slt i32 %a, %b
> -; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
> -; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
> -; CHECK-NEXT: %3 = or i32 %1, %2
> -; CHECK-NEXT: ret i32 %3
> +; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
> +; CHECK-NEXT: ret i32 [[result]]
>   }
>
>   define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
> @@ -71,8 +63,6 @@
>     %3 = or i32 %1, %2
>     ret i32 %3
>   ; CHECK: %0 = icmp slt i32 %a, %b
> -; CHECK-NEXT: %1 = select i1 %0, i32 %c, i32 0
> -; CHECK-NEXT: %2 = select i1 %0, i32 0, i32 %d
> -; CHECK-NEXT: %3 = or i32 %1, %2
> -; CHECK-NEXT: ret i32 %3
> +; CHECK-NEXT: [[result:%.*]] = select i1 %0, i32 %c, i32 %d
> +; CHECK-NEXT: ret i32 [[result]]
>   }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list