visitBR_CC is modified to support below IR change.
%2 = add %1, #const
br_cc cond %2, #const
-->
br_cc cond %1, 0
Differential D24327
[DAGCombine] Modification of visitBR_CC JongwonLee on Sep 7 2016, 7:37 PM. Authored by
Details
Diff Detail Event Timeline
Comment Actions
I don't think this transform is safe unless you have 'nsw' or 'nuw' on the add. Comment Actions am i missing something obvious? if nsw/nuw are present, then %2 could potentially be undef, and the transform would elide this case and alter semantics. so wouldn't it be unsafe only if the flags are present? Comment Actions The wrapping flags are what allow us to guarantee that the transform does not alter semantics. Consider the example with these values: %1 is i8 255 (unsigned max) %2 = add i8 %1, 1 br_cc ugt %2, 1 Wrapping is allowed; there is no undef. ugt 0, 1 --> false. If we make the transform suggested by this patch, the branch condition is: ugt 255, 0 --> true If the add has 'nuw', this case cannot occur. Otherwise, we have poison: Note that the semantics of DAG instructions are not actually specified/defined anywhere AFAIK (if they are, I'd love to know where!). I'm assuming they are the same as LLVM IR in this case because we can and do pass nsw/nuw flags from IR instructions to DAG nodes. Please take a look at how this transform is handled for signed and unsigned compares in InstCombineCompares.cpp. I assume the reason we need this fold repeated as a DAG combine is that the pattern does not emerge until it's too late to be handled by InstCombine? cc'ing Sanjoy and David in case I have any or all of this wrong. :) |
could this be generalized further? i.e., (br_cc cc, (add X, c0), c1, bb) => (br_cc cc, X, (c1 - c0), bb), assuming that c1 >= c0. and then generalize that to other binary ops?