<div dir="ltr">Just started looking at the example - this hangs somewhere in the backend, not in instcombine (IR below). Does that affect the decision about reverting?<br><br>$ ./llc -o - inf.ll -mtriple=x86_64<br>    .text<br>    .file    "inf.c"<br>^C<br><br>$ cat inf.ll<br>target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"<br>target triple = "x86_64--linux-gnu"<br><br>%struct.c = type { i32, [0 x i8] }<br><br>@d = common local_unnamed_addr global i32 0, align 4<br>@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* null }]<br>@__msan_retval_tls = external thread_local(initialexec) global [100 x i64]<br>@__msan_retval_origin_tls = external thread_local(initialexec) global i32<br>@__msan_param_tls = external thread_local(initialexec) global [100 x i64]<br>@__msan_param_origin_tls = external thread_local(initialexec) global [200 x i32]<br>@__msan_va_arg_tls = external thread_local(initialexec) global [100 x i64]<br>@__msan_va_arg_overflow_size_tls = external thread_local(initialexec) global i64<br>@__msan_origin_tls = external thread_local(initialexec) global i32<br><br>; Function Attrs: norecurse nounwind sanitize_memory<br>define i32 @e(%struct.c* %f) local_unnamed_addr #0 {<br>entry:<br>  %0 = load i64, i64* getelementptr inbounds ([100 x i64], [100 x i64]* @__msan_param_tls, i64 0, i64 0), align 8<br>  %1 = ptrtoint %struct.c* %f to i64<br>  %_msprop = trunc i64 %0 to i32<br>  %2 = trunc i64 %1 to i32<br>  store i32 0, i32* inttoptr (i64 xor (i64 ptrtoint (i32* @d to i64), i64 87960930222080) to i32*), align 4<br>  store i32 0, i32* @d, align 4, !tbaa !2<br>  %3 = icmp eq i32 %_msprop, 0<br>  br i1 %3, label %5, label %4, !prof !6<br><br>; <label>:4:                                      ; preds = %entry<br>  call void @__msan_warning_noreturn() #1<br>  call void asm sideeffect "", ""() #1<br>  unreachable<br><br>; <label>:5:                                      ; preds = %entry<br>  %cmp9 = icmp sgt i32 %2, 0<br>  br i1 %cmp9, label %<a href="http://for.body.lr.ph">for.body.lr.ph</a>, label %for.end<br><br><a href="http://for.body.lr.ph">for.body.lr.ph</a>:                                   ; preds = %5<br>  %_msprop23 = trunc i64 %0 to i8<br>  %6 = trunc i64 %1 to i8<br>  %arrayidx.phi.trans.insert = getelementptr inbounds %struct.c, %struct.c* %f, i64 0, i32 1, i64 0<br>  %_mscmp54 = icmp eq i64 %0, 0<br>  br i1 %_mscmp54, label %8, label %7, !prof !6<br><br>; <label>:7:                                      ; preds = %<a href="http://for.body.lr.ph">for.body.lr.ph</a><br>  call void @__msan_warning_noreturn() #1<br>  call void asm sideeffect "", ""() #1<br>  unreachable<br><br>; <label>:8:                                      ; preds = %<a href="http://for.body.lr.ph">for.body.lr.ph</a><br>  %.pre = load i8, i8* %arrayidx.phi.trans.insert, align 1, !tbaa !7<br>  %9 = ptrtoint i8* %arrayidx.phi.trans.insert to i64<br>  %10 = xor i64 %9, 87960930222080<br>  %11 = inttoptr i64 %10 to i8*<br>  %_msld = load i8, i8* %11, align 1<br>  %wide.trip.count = and i64 %1, 4294967295<br>  br i1 false, label %12, label %13, !prof !8<br><br>; <label>:12:                                     ; preds = %8<br>  unreachable<br><br>; <label>:13:                                     ; preds = %8<br>  %14 = icmp ult i64 %wide.trip.count, 32<br>  br i1 %14, label %for.body.preheader, label %<a href="http://vector.ph">vector.ph</a><br><br><a href="http://vector.ph">vector.ph</a>:                                        ; preds = %13<br>  %n.mod.vf = and i64 %1, 31<br>  %n.vec = sub nsw i64 %wide.trip.count, %n.mod.vf<br>  %cast.crd = trunc i64 %n.vec to i8<br>  %15 = mul i8 %cast.crd, %6<br>  %_msprop33 = or i8 %_msld, %_msprop23<br>  %ind.end = add i8 %.pre, %15<br>  %_msprop34 = insertelement <16 x i8> undef, i8 %_msld, i32 0<br>  %.splatinsert = insertelement <16 x i8> undef, i8 %.pre, i32 0<br>  %_msprop35 = shufflevector <16 x i8> %_msprop34, <16 x i8> undef, <16 x i32> zeroinitializer<br>  %.splat = shufflevector <16 x i8> %.splatinsert, <16 x i8> undef, <16 x i32> zeroinitializer<br>  %_msprop36 = insertelement <16 x i8> undef, i8 %_msprop23, i32 0<br>  %.splatinsert12 = insertelement <16 x i8> undef, i8 %6, i32 0<br>  %_msprop37 = shufflevector <16 x i8> %_msprop36, <16 x i8> undef, <16 x i32> zeroinitializer<br>  %.splat13 = shufflevector <16 x i8> %.splatinsert12, <16 x i8> undef, <16 x i32> zeroinitializer<br>  %msprop_mul_cst = mul <16 x i8> %_msprop37, <i8 0, i8 1, i8 2, i8 1, i8 4, i8 1, i8 2, i8 1, i8 8, i8 1, i8 2, i8 1, i8 4, i8 1, i8 2, i8 1><br>  %16 = mul <16 x i8> %.splat13, <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15><br>  %_msprop38 = or <16 x i8> %_msprop35, %msprop_mul_cst<br>  %induction = add <16 x i8> %.splat, %16<br>  %17 = shl i8 %_msprop23, 4<br>  %18 = shl i8 %6, 4<br>  %_msprop39 = insertelement <16 x i8> undef, i8 %17, i32 0<br>  %.splatinsert14 = insertelement <16 x i8> undef, i8 %18, i32 0<br>  %_msprop40 = shufflevector <16 x i8> %_msprop39, <16 x i8> undef, <16 x i32> zeroinitializer<br>  %.splat15 = shufflevector <16 x i8> %.splatinsert14, <16 x i8> undef, <16 x i32> zeroinitializer<br>  br label %vector.body<br><br>vector.body:                                      ; preds = %37, %<a href="http://vector.ph">vector.ph</a><br>  %index = phi i64 [ 0, %<a href="http://vector.ph">vector.ph</a> ], [ %index.next, %37 ]<br>  %_msphi_s46 = phi <16 x i8> [ %_msprop38, %<a href="http://vector.ph">vector.ph</a> ], [ %_msprop47, %37 ]<br>  %vec.ind = phi <16 x i8> [ %induction, %<a href="http://vector.ph">vector.ph</a> ], [ %vec.ind.next, %37 ]<br>  %_msprop47 = or <16 x i8> %_msphi_s46, %_msprop40<br>  %step.add = add <16 x i8> %vec.ind, %.splat15<br>  %_msprop49 = or <16 x i8> %_msprop47, %_msprop37<br>  %19 = add <16 x i8> %step.add, %.splat13<br>  %20 = or i64 %index, 1<br>  %21 = getelementptr inbounds %struct.c, %struct.c* %f, i64 0, i32 1, i64 %20<br>  br i1 false, label %22, label %23, !prof !8<br><br>; <label>:22:                                     ; preds = %vector.body<br>  unreachable<br><br>; <label>:23:                                     ; preds = %vector.body<br>  %24 = ptrtoint i8* %21 to i64<br>  %25 = xor i64 %24, 87960930222080<br>  %26 = inttoptr i64 %25 to <16 x i8>*<br>  %27 = bitcast i8* %21 to <16 x i8>*<br>  %28 = add <16 x i8> %vec.ind, %.splat13<br>  %_msprop48 = or <16 x i8> %_msphi_s46, %_msprop37<br>  store <16 x i8> %_msprop48, <16 x i8>* %26, align 1<br>  store <16 x i8> %28, <16 x i8>* %27, align 1, !tbaa !7<br>  %29 = getelementptr i8, i8* %21, i64 16<br>  br i1 false, label %30, label %31, !prof !8<br><br>; <label>:30:                                     ; preds = %23<br>  unreachable<br><br>; <label>:31:                                     ; preds = %23<br>  %32 = ptrtoint i8* %29 to i64<br>  %33 = xor i64 %32, 87960930222080<br>  %34 = inttoptr i64 %33 to <16 x i8>*<br>  %35 = bitcast i8* %29 to <16 x i8>*<br>  store <16 x i8> %_msprop49, <16 x i8>* %34, align 1<br>  store <16 x i8> %19, <16 x i8>* %35, align 1, !tbaa !7<br>  %index.next = add i64 %index, 32<br>  br i1 false, label %36, label %37, !prof !8<br><br>; <label>:36:                                     ; preds = %31<br>  unreachable<br><br>; <label>:37:                                     ; preds = %31<br>  %38 = icmp eq i64 %index.next, %n.vec<br>  %vec.ind.next = add <16 x i8> %step.add, %.splat15<br>  br i1 %38, label %middle.block, label %vector.body, !llvm.loop !9<br><br>middle.block:                                     ; preds = %37<br>  br i1 false, label %39, label %40, !prof !8<br><br>; <label>:39:                                     ; preds = %middle.block<br>  unreachable<br><br>; <label>:40:                                     ; preds = %middle.block<br>  %41 = icmp eq i64 %n.mod.vf, 0<br>  br i1 %41, label %for.cond.for.end_crit_edge, label %for.body.preheader<br><br>for.body.preheader:                               ; preds = %40, %13<br>  %_msphi_s = phi i8 [ %_msld, %13 ], [ %_msprop33, %40 ]<br>  %.ph = phi i8 [ %.pre, %13 ], [ %ind.end, %40 ]<br>  %<a href="http://indvars.iv.ph">indvars.iv.ph</a> = phi i64 [ 0, %13 ], [ %n.vec, %40 ]<br>  br label %for.body<br><br>for.body:                                         ; preds = %for.body.preheader, %49<br>  %_msphi_s25 = phi i8 [ %_msprop27, %49 ], [ %_msphi_s, %for.body.preheader ]<br>  %42 = phi i8 [ %conv1, %49 ], [ %.ph, %for.body.preheader ]<br>  %indvars.iv = phi i64 [ %indvars.iv.next, %49 ], [ %<a href="http://indvars.iv.ph">indvars.iv.ph</a>, %for.body.preheader ]<br>  %_msprop27 = or i8 %_msphi_s25, %_msprop23<br>  %conv1 = add i8 %42, %6<br>  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1<br>  %arrayidx5 = getelementptr inbounds %struct.c, %struct.c* %f, i64 0, i32 1, i64 %indvars.iv.next<br>  br i1 false, label %43, label %44, !prof !8<br><br>; <label>:43:                                     ; preds = %for.body<br>  unreachable<br><br>; <label>:44:                                     ; preds = %for.body<br>  %45 = ptrtoint i8* %arrayidx5 to i64<br>  %46 = xor i64 %45, 87960930222080<br>  %47 = inttoptr i64 %46 to i8*<br>  store i8 %_msprop27, i8* %47, align 1<br>  store i8 %conv1, i8* %arrayidx5, align 1, !tbaa !7<br>  br i1 false, label %48, label %49, !prof !8<br><br>; <label>:48:                                     ; preds = %44<br>  unreachable<br><br>; <label>:49:                                     ; preds = %44<br>  %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count<br>  br i1 %exitcond, label %for.cond.for.end_crit_edge.loopexit, label %for.body, !llvm.loop !11<br><br>for.cond.for.end_crit_edge.loopexit:              ; preds = %49<br>  br label %for.cond.for.end_crit_edge<br><br>for.cond.for.end_crit_edge:                       ; preds = %for.cond.for.end_crit_edge.loopexit, %40<br>  store i32 0, i32* inttoptr (i64 xor (i64 ptrtoint (i32* @d to i64), i64 87960930222080) to i32*), align 4<br>  store i32 %2, i32* @d, align 4, !tbaa !2<br>  br label %for.end<br><br>for.end:                                          ; preds = %for.cond.for.end_crit_edge, %5<br>  store i32 -1, i32* bitcast ([100 x i64]* @__msan_retval_tls to i32*), align 8<br>  ret i32 undef<br>}<br><br>declare void @__msan_init() local_unnamed_addr<br><br>define internal void @msan.module_ctor() {<br>  tail call void @__msan_init()<br>  ret void<br>}<br><br>declare void @__msan_warning_noreturn()<br><br>declare void @__msan_maybe_warning_1(i8, i32)<br><br>declare void @__msan_maybe_store_origin_1(i8, i8*, i32)<br><br>declare void @__msan_maybe_warning_2(i16, i32)<br><br>declare void @__msan_maybe_store_origin_2(i16, i8*, i32)<br><br>declare void @__msan_maybe_warning_4(i32, i32)<br><br>declare void @__msan_maybe_store_origin_4(i32, i8*, i32)<br><br>declare void @__msan_maybe_warning_8(i64, i32)<br><br>declare void @__msan_maybe_store_origin_8(i64, i8*, i32)<br><br>declare void @__msan_set_alloca_origin4(i8*, i64, i8*, i64)<br><br>declare void @__msan_poison_stack(i8*, i64)<br><br>declare i32 @__msan_chain_origin(i32)<br><br>declare i8* @__msan_memmove(i8*, i8*, i64)<br><br>declare i8* @__msan_memcpy(i8*, i8*, i64)<br><br>declare i8* @__msan_memset(i8*, i32, i64)<br><br>attributes #0 = { norecurse nounwind sanitize_memory "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }<br>attributes #1 = { nounwind }<br><br>!llvm.module.flags = !{!0}<br>!llvm.ident = !{!1}<br><br>!0 = !{i32 1, !"wchar_size", i32 4}<br>!1 = !{!"clang version 6.0.0 (trunk 320064) (llvm/trunk 320063)"}<br>!2 = !{!3, !3, i64 0}<br>!3 = !{!"int", !4, i64 0}<br>!4 = !{!"omnipotent char", !5, i64 0}<br>!5 = !{!"Simple C/C++ TBAA"}<br>!6 = !{!"branch_weights", i32 1000, i32 1}<br>!7 = !{!4, !4, i64 0}<br>!8 = !{!"branch_weights", i32 1, i32 1000}<br>!9 = distinct !{!9, !10}<br>!10 = !{!"llvm.loop.isvectorized", i32 1}<br>!11 = distinct !{!11, !12, !10}<br>!12 = !{!"llvm.loop.unroll.runtime.disable"}<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 8, 2017 at 3:24 AM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I think this is still enough of a test case to revert while we sort it out.</div><div class="HOEnZb"><div class="h5"><br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 8, 2017 at 4:38 AM David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Haven't looked too far yet, but here's my current repro:<br><br><div>typedef struct {</div><div>  int a;</div><div>  char b[]</div><div>} c;</div><div>d;</div><div>e(c *f) {</div><div>  int g, h = g = f;</div><div>  d = 0;</div><div>  for (; d < h; d++)</div><div>    f->b[d + 1] = f->b[d] + g;</div><div>}<br><br>clang -cc1 -emit-obj -triple x86_64-linux-gnu -target-feature +sse4.2 -O2 -w -fsanitize=memory -vectorize-loops -o /dev/null foo.ii -x c<br><br>Appears to run forever/a long time.<br><br>Interestingly, a nearby test case seems to fail with or without the patch:<br><br><span style="font-family:monospace;font-size:13px">typedef struct {</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">  int a;</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">  char b[]</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">} c;</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">d;</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">e(c *f) {</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">  int g = f;</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">  for (; d; d++)</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">    f->b[d + 1] = f->b[d] + g;</span><br style="font-family:monospace;font-size:13px"><span style="font-family:monospace;font-size:13px">}<br></span><br>So I guess this might be one of those unfortunate cases of an optimization causing further exposure to an existing bug, but still.. </div></div><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 7, 2017 at 1:56 PM Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Thanks for letting me know.<br><br></div>This might be a good time to check out (though I haven't gotten to it yet):<br><a href="https://github.com/rutgers-apl/alive-loops" target="_blank">https://github.com/rutgers-<wbr>apl/alive-loops</a><br><div class="gmail_extra"><br></div><div class="gmail_extra">This was mentioned on llvm-dev:</div><div class="gmail_extra"><a href="http://lists.llvm.org/pipermail/llvm-dev/2017-September/117466.html" target="_blank">http://lists.llvm.org/<wbr>pipermail/llvm-dev/2017-<wbr>September/117466.html</a><br></div></div><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 7, 2017 at 12:48 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@gmail.com" target="_blank">chandlerc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">FYI, we've root caused an compile timeout to this revision. It seems quite likely this is fighting another instcombine.<div><br></div><div>We're still working on a test case, but wanted to go ahead and give a heads-up in case you can spot the place where we reverse this transform.<div><div class="m_2622050965969556890m_5372016222329087132m_-8438521976343846489m_2461758821938462947gmail-m_2453132479159311356h5"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 15, 2017 at 8:12 PM Sanjay Patel via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: spatel<br>
Date: Wed Nov 15 11:12:01 2017<br>
New Revision: 318323<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=318323&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=318323&view=rev</a><br>
Log:<br>
[InstCombine] trunc (binop X, C) --> binop (trunc X, C')<br>
<br>
Note that one-use and shouldChangeType() are checked ahead of the switch.<br>
<br>
Without the narrowing folds, we can produce inferior vector code as shown in PR35299:<br>
<a href="https://bugs.llvm.org/show_bug.cgi?id=35299" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_<wbr>bug.cgi?id=35299</a><br>
<br>
<br>
Modified:<br>
    llvm/trunk/lib/Transforms/<wbr>InstCombine/InstCombineCasts.<wbr>cpp<br>
    llvm/trunk/test/Transforms/<wbr>InstCombine/pr33765.ll<br>
    llvm/trunk/test/Transforms/<wbr>InstCombine/trunc-binop-ext.ll<br>
<br>
Modified: llvm/trunk/lib/Transforms/<wbr>InstCombine/InstCombineCasts.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=318323&r1=318322&r2=318323&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/lib/<wbr>Transforms/InstCombine/<wbr>InstCombineCasts.cpp?rev=<wbr>318323&r1=318322&r2=318323&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/<wbr>InstCombine/InstCombineCasts.<wbr>cpp (original)<br>
+++ llvm/trunk/lib/Transforms/<wbr>InstCombine/InstCombineCasts.<wbr>cpp Wed Nov 15 11:12:01 2017<br>
@@ -545,6 +545,8 @@ Instruction *InstCombiner::narrowBinOp(T<br>
   if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(BinOp))))<br>
     return nullptr;<br>
<br>
+  Value *BinOp0 = BinOp->getOperand(0);<br>
+  Value *BinOp1 = BinOp->getOperand(1);<br>
   switch (BinOp->getOpcode()) {<br>
   case Instruction::And:<br>
   case Instruction::Or:<br>
@@ -552,20 +554,31 @@ Instruction *InstCombiner::narrowBinOp(T<br>
   case Instruction::Add:<br>
   case Instruction::Mul: {<br>
     Constant *C;<br>
-    if (match(BinOp->getOperand(1), m_Constant(C))) {<br>
+    if (match(BinOp1, m_Constant(C))) {<br>
       // trunc (binop X, C) --> binop (trunc X, C')<br>
       Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);<br>
-      Value *TruncX = Builder.CreateTrunc(BinOp-><wbr>getOperand(0), DestTy);<br>
+      Value *TruncX = Builder.CreateTrunc(BinOp0, DestTy);<br>
       return BinaryOperator::Create(BinOp-><wbr>getOpcode(), TruncX, NarrowC);<br>
     }<br>
+    Value *X;<br>
+    if (match(BinOp0, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {<br>
+      // trunc (binop (ext X), Y) --> binop X, (trunc Y)<br>
+      Value *NarrowOp1 = Builder.CreateTrunc(BinOp1, DestTy);<br>
+      return BinaryOperator::Create(BinOp-><wbr>getOpcode(), X, NarrowOp1);<br>
+    }<br>
+    if (match(BinOp1, m_ZExtOrSExt(m_Value(X))) && X->getType() == DestTy) {<br>
+      // trunc (binop Y, (ext X)) --> binop (trunc Y), X<br>
+      Value *NarrowOp0 = Builder.CreateTrunc(BinOp0, DestTy);<br>
+      return BinaryOperator::Create(BinOp-><wbr>getOpcode(), NarrowOp0, X);<br>
+    }<br>
     break;<br>
   }<br>
   case Instruction::Sub: {<br>
     Constant *C;<br>
-    if (match(BinOp->getOperand(0), m_Constant(C))) {<br>
+    if (match(BinOp0, m_Constant(C))) {<br>
       // trunc (binop C, X) --> binop (trunc C', X)<br>
       Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);<br>
-      Value *TruncX = Builder.CreateTrunc(BinOp-><wbr>getOperand(1), DestTy);<br>
+      Value *TruncX = Builder.CreateTrunc(BinOp1, DestTy);<br>
       return BinaryOperator::Create(BinOp-><wbr>getOpcode(), NarrowC, TruncX);<br>
     }<br>
     break;<br>
<br>
Modified: llvm/trunk/test/Transforms/<wbr>InstCombine/pr33765.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/pr33765.ll?rev=318323&r1=318322&r2=318323&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/InstCombine/<wbr>pr33765.ll?rev=318323&r1=<wbr>318322&r2=318323&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/Transforms/<wbr>InstCombine/pr33765.ll (original)<br>
+++ llvm/trunk/test/Transforms/<wbr>InstCombine/pr33765.ll Wed Nov 15 11:12:01 2017<br>
@@ -10,9 +10,8 @@ define void @patatino(i8 %beth) {<br>
 ; CHECK:       if.then9:<br>
 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[CONV]], [[CONV]]<br>
 ; CHECK-NEXT:    [[TINKY:%.*]] = load i16, i16* @glob, align 2<br>
-; CHECK-NEXT:    [[CONV131:%.*]] = zext i16 [[TINKY]] to i32<br>
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[MUL]], [[CONV131]]<br>
-; CHECK-NEXT:    [[CONV14:%.*]] = trunc i32 [[AND]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[MUL]] to i16<br>
+; CHECK-NEXT:    [[CONV14:%.*]] = and i16 [[TINKY]], [[TMP1]]<br>
 ; CHECK-NEXT:    store i16 [[CONV14]], i16* @glob, align 2<br>
 ; CHECK-NEXT:    ret void<br>
 ;<br>
<br>
Modified: llvm/trunk/test/Transforms/<wbr>InstCombine/trunc-binop-ext.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/trunc-binop-ext.ll?rev=318323&r1=318322&r2=318323&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/test/<wbr>Transforms/InstCombine/trunc-<wbr>binop-ext.ll?rev=318323&r1=<wbr>318322&r2=318323&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/Transforms/<wbr>InstCombine/trunc-binop-ext.ll (original)<br>
+++ llvm/trunk/test/Transforms/<wbr>InstCombine/trunc-binop-ext.ll Wed Nov 15 11:12:01 2017<br>
@@ -2,9 +2,8 @@<br>
<br>
 define i16 @narrow_sext_and(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_and(<br>
-; CHECK-NEXT:    [[X321:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = and i32 [[X321]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = and i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = sext i16 %x16 to i32<br>
@@ -15,9 +14,8 @@ define i16 @narrow_sext_and(i16 %x16, i3<br>
<br>
 define i16 @narrow_zext_and(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_and(<br>
-; CHECK-NEXT:    [[X32:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = and i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = and i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = zext i16 %x16 to i32<br>
@@ -28,9 +26,8 @@ define i16 @narrow_zext_and(i16 %x16, i3<br>
<br>
 define i16 @narrow_sext_or(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_or(<br>
-; CHECK-NEXT:    [[X321:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = or i32 [[X321]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = or i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = sext i16 %x16 to i32<br>
@@ -41,9 +38,8 @@ define i16 @narrow_sext_or(i16 %x16, i32<br>
<br>
 define i16 @narrow_zext_or(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_or(<br>
-; CHECK-NEXT:    [[X32:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = or i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = or i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = zext i16 %x16 to i32<br>
@@ -54,9 +50,8 @@ define i16 @narrow_zext_or(i16 %x16, i32<br>
<br>
 define i16 @narrow_sext_xor(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_xor(<br>
-; CHECK-NEXT:    [[X321:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X321]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = xor i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = sext i16 %x16 to i32<br>
@@ -67,9 +62,8 @@ define i16 @narrow_sext_xor(i16 %x16, i3<br>
<br>
 define i16 @narrow_zext_xor(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_xor(<br>
-; CHECK-NEXT:    [[X32:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = xor i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = xor i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = zext i16 %x16 to i32<br>
@@ -80,9 +74,8 @@ define i16 @narrow_zext_xor(i16 %x16, i3<br>
<br>
 define i16 @narrow_sext_add(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_add(<br>
-; CHECK-NEXT:    [[X321:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = add i32 [[X321]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = add i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = sext i16 %x16 to i32<br>
@@ -93,9 +86,8 @@ define i16 @narrow_sext_add(i16 %x16, i3<br>
<br>
 define i16 @narrow_zext_add(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_add(<br>
-; CHECK-NEXT:    [[X32:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = add i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = add i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = zext i16 %x16 to i32<br>
@@ -106,9 +98,8 @@ define i16 @narrow_zext_add(i16 %x16, i3<br>
<br>
 define i16 @narrow_sext_mul(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_mul(<br>
-; CHECK-NEXT:    [[X32:%.*]] = sext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = mul i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = sext i16 %x16 to i32<br>
@@ -119,9 +110,8 @@ define i16 @narrow_sext_mul(i16 %x16, i3<br>
<br>
 define i16 @narrow_zext_mul(i16 %x16, i32 %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_mul(<br>
-; CHECK-NEXT:    [[X32:%.*]] = zext i16 %x16 to i32<br>
-; CHECK-NEXT:    [[B:%.*]] = mul i32 [[X32]], %y32<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[B]] to i16<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %y32 to i16<br>
+; CHECK-NEXT:    [[R:%.*]] = mul i16 [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret i16 [[R]]<br>
 ;<br>
   %x32 = zext i16 %x16 to i32<br>
@@ -130,15 +120,14 @@ define i16 @narrow_zext_mul(i16 %x16, i3<br>
   ret i16 %r<br>
 }<br>
<br>
-; Verify that the commuted patterns work. The div is to ensure that complexity-based<br>
+; Verify that the commuted patterns work. The div is to ensure that complexity-based<br>
 ; canonicalization doesn't swap the binop operands. Use vector types to show those work too.<br>
<br>
 define <2 x i16> @narrow_sext_and_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_and_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[Y32OP0]], [[X321]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -151,9 +140,8 @@ define <2 x i16> @narrow_sext_and_commut<br>
 define <2 x i16> @narrow_zext_and_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_and_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = and <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -166,9 +154,8 @@ define <2 x i16> @narrow_zext_and_commut<br>
 define <2 x i16> @narrow_sext_or_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_or_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[Y32OP0]], [[X321]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = or <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -181,9 +168,8 @@ define <2 x i16> @narrow_sext_or_commute<br>
 define <2 x i16> @narrow_zext_or_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_or_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = or <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -196,9 +182,8 @@ define <2 x i16> @narrow_zext_or_commute<br>
 define <2 x i16> @narrow_sext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_xor_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i32> [[Y32OP0]], [[X321]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -211,9 +196,8 @@ define <2 x i16> @narrow_sext_xor_commut<br>
 define <2 x i16> @narrow_zext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_xor_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -226,9 +210,8 @@ define <2 x i16> @narrow_zext_xor_commut<br>
 define <2 x i16> @narrow_sext_add_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_add_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X321:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> [[Y32OP0]], [[X321]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = add <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -241,9 +224,8 @@ define <2 x i16> @narrow_sext_add_commut<br>
 define <2 x i16> @narrow_zext_add_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_add_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = add <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = add <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -256,9 +238,8 @@ define <2 x i16> @narrow_zext_add_commut<br>
 define <2 x i16> @narrow_sext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_sext_mul_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = sext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = mul <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
@@ -271,9 +252,8 @@ define <2 x i16> @narrow_sext_mul_commut<br>
 define <2 x i16> @narrow_zext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) {<br>
 ; CHECK-LABEL: @narrow_zext_mul_commute(<br>
 ; CHECK-NEXT:    [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
-; CHECK-NEXT:    [[X32:%.*]] = zext <2 x i16> %x16 to <2 x i32><br>
-; CHECK-NEXT:    [[B:%.*]] = mul <2 x i32> [[Y32OP0]], [[X32]]<br>
-; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i32> [[B]] to <2 x i16><br>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16><br>
+; CHECK-NEXT:    [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16<br>
 ; CHECK-NEXT:    ret <2 x i16> [[R]]<br>
 ;<br>
   %y32op0 = sdiv <2 x i32> %y32, <i32 7, i32 -17><br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div></div></div>
</blockquote></div><br></div></div></blockquote></div></div></blockquote></div>
</div></div></blockquote></div><br></div>