<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, Jul 14, 2015 at 5:22 PM Michael Zolotukhin <<a href="mailto:mzolotukhin@apple.com">mzolotukhin@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mzolotukhin<br>
Date: Tue Jul 14 19:19:51 2015<br>
New Revision: 242257<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D242257-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=aeDNgFzYYlxzBWazW8MWK-GCQTDl3d3F6R-WR-yuK3o&s=V09aFpu0XmwYPfyjmIjJYuJ7ujG_ybQz_-Ch5fE2VxY&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=242257&view=rev</a><br>
Log:<br>
[LoopUnrolling] Handle cast instructions.<br>
<br>
During estimation of unrolling effect we should be able to propagate<br>
constants through casts.<br>
<br>
Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10207&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=aeDNgFzYYlxzBWazW8MWK-GCQTDl3d3F6R-WR-yuK3o&s=0fO5wvBwTJ4TuRkNyt7-mirIImrDvfYmongHYha_2fw&e=" rel="noreferrer" target="_blank">http://reviews.llvm.org/D10207</a><br>
<br>
Added:<br>
    llvm/trunk/test/Transforms/LoopUnroll/full-unroll-heuristics-cast.ll<br>
Modified:<br>
    llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Transforms_Scalar_LoopUnrollPass.cpp-3Frev-3D242257-26r1-3D242256-26r2-3D242257-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=aeDNgFzYYlxzBWazW8MWK-GCQTDl3d3F6R-WR-yuK3o&s=p9Q4vA7Q5BsDnrmMmFUPwYXMppSZcl-LyhQMOPZVZEY&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=242257&r1=242256&r2=242257&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Tue Jul 14 19:19:51 2015<br>
@@ -436,6 +436,21 @@ private:<br>
<br>
     return true;<br>
   }<br>
+<br>
+  bool visitCastInst(CastInst &I) {<br>
+    // Propagate constants through casts.<br>
+    Constant *COp = dyn_cast<Constant>(I.getOperand(0));<br>
+    if (!COp)<br>
+      COp = SimplifiedValues.lookup(I.getOperand(0));<br>
+    if (COp)<br>
+      if (Constant *C =<br>
+              ConstantExpr::getCast(I.getOpcode(), COp, I.getType())) {<br>
+        SimplifiedValues[&I] = C;<br>
+        return true;<br>
+      }<br>
+<br>
+    return Base::visitCastInst(I);<br>
+  }<br>
 };<br>
 } // namespace<br>
<br>
<br>
Added: llvm/trunk/test/Transforms/LoopUnroll/full-unroll-heuristics-cast.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_Transforms_LoopUnroll_full-2Dunroll-2Dheuristics-2Dcast.ll-3Frev-3D242257-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=aeDNgFzYYlxzBWazW8MWK-GCQTDl3d3F6R-WR-yuK3o&s=URyjH3UMg40xXUk3qX6BH9hjM-EjZrxu-A_fxrug_e4&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/full-unroll-heuristics-cast.ll?rev=242257&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/LoopUnroll/full-unroll-heuristics-cast.ll (added)<br>
+++ llvm/trunk/test/Transforms/LoopUnroll/full-unroll-heuristics-cast.ll Tue Jul 14 19:19:51 2015<br>
@@ -0,0 +1,94 @@<br>
+; RUN: opt < %s -S -loop-unroll -unroll-max-iteration-count-to-analyze=100 -unroll-dynamic-cost-savings-discount=1000 -unroll-threshold=10 -unroll-percent-dynamic-cost-saved-threshold=50 | FileCheck %s<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+<br>
+@known_constant = internal unnamed_addr constant [10 x i32] [i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1], align 16<br>
+<br>
+; We should be able to propagate constant data thru different types of casts.<br>
+; For example, in this test we have a load, which becomes constant after<br>
+; unrolling, which then is truncated to i8. Obviously, truncated value is also a<br>
+; constant, which can be used in the further simplifications.<br>
+;<br>
+; We expect this loop to be unrolled, because in this case load would become<br>
+; constant, which is 0 in many cases, and which, in its turn, helps to simplify<br>
+; following multiplication and addition. In total, unrolling should help to<br>
+; optimize  ~60% of all instructions in this case.<br>
+;<br>
+; CHECK-LABEL: @const_load_trunc<br>
+; CHECK-NOT: br i1 %exitcond86.i, label %loop.end, label %loop<br></blockquote><div><br></div><div>This is a really brittle test. The -NOT could fire because the *name* was wrong.</div><div><br></div><div>Can you check for no 'br i1's? Maybe check for the existence of some branch or ret instructions though so that an empty function doesn't match?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+define i8 @const_load_trunc(i32* noalias nocapture readonly %src) {<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:                                                ; preds = %loop, %entry<br>
+  %iv = phi i64 [ 0, %entry ], [ %inc, %loop ]<br>
+  %r  = phi i8 [ 0, %entry ], [ %add, %loop ]<br>
+  %arrayidx = getelementptr inbounds i32, i32* %src, i64 %iv<br>
+  %src_element = load i32, i32* %arrayidx, align 4<br>
+  %array_const_idx = getelementptr inbounds [10 x i32], [10 x i32]* @known_constant, i64 0, i64 %iv<br>
+  %const_array_element = load i32, i32* %array_const_idx, align 4<br>
+  %x = trunc i32 %src_element to i8<br>
+  %y = trunc i32 %const_array_element to i8<br>
+  %mul = mul nsw i8 %x, %y<br>
+  %add = add nsw i8 %mul, %r<br>
+  %inc = add nuw nsw i64 %iv, 1<br>
+  %exitcond86.i = icmp eq i64 %inc, 10<br>
+  br i1 %exitcond86.i, label %loop.end, label %loop<br>
+<br>
+loop.end:                                            ; preds = %loop<br>
+  %r.lcssa = phi i8 [ %r, %loop ]<br>
+  ret i8 %r.lcssa<br>
+}<br>
+<br>
+; The same test as before, but with ZEXT instead of TRUNC.<br>
+; CHECK-LABEL: @const_load_zext<br>
+; CHECK-NOT: br i1 %exitcond86.i, label %loop.end, label %loop<br>
+define i64 @const_load_zext(i32* noalias nocapture readonly %src) {<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:                                                ; preds = %loop, %entry<br>
+  %iv = phi i64 [ 0, %entry ], [ %inc, %loop ]<br>
+  %r  = phi i64 [ 0, %entry ], [ %add, %loop ]<br>
+  %arrayidx = getelementptr inbounds i32, i32* %src, i64 %iv<br>
+  %src_element = load i32, i32* %arrayidx, align 4<br>
+  %array_const_idx = getelementptr inbounds [10 x i32], [10 x i32]* @known_constant, i64 0, i64 %iv<br>
+  %const_array_element = load i32, i32* %array_const_idx, align 4<br>
+  %x = zext i32 %src_element to i64<br>
+  %y = zext i32 %const_array_element to i64<br>
+  %mul = mul nsw i64 %x, %y<br>
+  %add = add nsw i64 %mul, %r<br>
+  %inc = add nuw nsw i64 %iv, 1<br>
+  %exitcond86.i = icmp eq i64 %inc, 10<br>
+  br i1 %exitcond86.i, label %loop.end, label %loop<br>
+<br>
+loop.end:                                            ; preds = %loop<br>
+  %r.lcssa = phi i64 [ %r, %loop ]<br>
+  ret i64 %r.lcssa<br>
+}<br>
+<br>
+; The same test as the first one, but with SEXT instead of TRUNC.<br>
+; CHECK-LABEL: @const_load_sext<br>
+; CHECK-NOT: br i1 %exitcond86.i, label %loop.end, label %loop<br>
+define i64 @const_load_sext(i32* noalias nocapture readonly %src) {<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:                                                ; preds = %loop, %entry<br>
+  %iv = phi i64 [ 0, %entry ], [ %inc, %loop ]<br>
+  %r  = phi i64 [ 0, %entry ], [ %add, %loop ]<br>
+  %arrayidx = getelementptr inbounds i32, i32* %src, i64 %iv<br>
+  %src_element = load i32, i32* %arrayidx, align 4<br>
+  %array_const_idx = getelementptr inbounds [10 x i32], [10 x i32]* @known_constant, i64 0, i64 %iv<br>
+  %const_array_element = load i32, i32* %array_const_idx, align 4<br>
+  %x = sext i32 %src_element to i64<br>
+  %y = sext i32 %const_array_element to i64<br>
+  %mul = mul nsw i64 %x, %y<br>
+  %add = add nsw i64 %mul, %r<br>
+  %inc = add nuw nsw i64 %iv, 1<br>
+  %exitcond86.i = icmp eq i64 %inc, 10<br>
+  br i1 %exitcond86.i, label %loop.end, label %loop<br>
+<br>
+loop.end:                                            ; preds = %loop<br>
+  %r.lcssa = phi i64 [ %r, %loop ]<br>
+  ret i64 %r.lcssa<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>