[PATCH] Fix a bug in DAGcombiner about zero-extend after setcc.
Owen Anderson
resistor at mac.com
Sat Dec 28 00:31:02 PST 2013
LGTM.
—Owen
On Dec 26, 2013, at 5:47 PM, Kevin Qin <kevinqindev at gmail.com> wrote:
> This bug is exposed in AArch64 backend.
>
> For below IR,
> {code}
> define <8 x i16> @test(<8 x i8> %a, <8 x i8> %b) #0 {
> entry:
> %cmp.i = icmp eq <8 x i8> %a, %b
> %vcgtz.i.i = sext <8 x i1> %cmp.i to <8 x i8>
> %vmovl.i.i.i = zext <8 x i8> %vcgtz.i.i to <8 x i16>
> ret <8 x i16> %vmovl.i.i.i
> }
> {code}
> We expect
> {code}
> cmeq v0.8b, v0.8b, v1.8b
> ushll v0.8h, v0.8b, #0
> {code}
> But we got
> {code}
> cmeq v0.8b, v0.8b, v1.8b
> sshll v0.8h, v0.8b, #0
> movi v1.8h, #0x1
> and v0.16b, v0.16b, v1.16b
> {code}
> High bits of each element are set to 0 except bit[0].
>
> The reason is in DAGcombiner, if it see "sext(setcc)", it will combine them together to a single setcc with extended value type. Then if it see "zext(setcc)", it assumes setcc is Vxi1, and try to create "(and (vsetcc), (1, 1, ...)". While setcc isn't Vxi1, DAGcombiner will create wrong node and get wrong code emitted.
>
> http://llvm-reviews.chandlerc.com/D2477
>
> Files:
> lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> test/CodeGen/AArch64/neon-shift-left-long.ll
>
> Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> ===================================================================
> --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> @@ -4970,7 +4970,8 @@
> }
>
> if (N0.getOpcode() == ISD::SETCC) {
> - if (!LegalOperations && VT.isVector()) {
> + if (!LegalOperations && VT.isVector() &&
> + N0.getValueType().getVectorElementType() == MVT::i1) {
> // zext(setcc) -> (and (vsetcc), (1, 1, ...) for vectors.
> // Only do this before legalize for now.
> EVT N0VT = N0.getOperand(0).getValueType();
> Index: test/CodeGen/AArch64/neon-shift-left-long.ll
> ===================================================================
> --- test/CodeGen/AArch64/neon-shift-left-long.ll
> +++ test/CodeGen/AArch64/neon-shift-left-long.ll
> @@ -191,3 +191,13 @@
> %tmp = zext <2 x i32> %1 to <2 x i64>
> ret <2 x i64> %tmp
> }
> +
> +define <8 x i16> @test_ushll_cmp(<8 x i8> %a, <8 x i8> %b) #0 {
> +; CHECK: test_ushll_cmp:
> +; CHECK: cmeq {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
> +; CHECK-NEXT: ushll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #0
> + %cmp.i = icmp eq <8 x i8> %a, %b
> + %vcgtz.i.i = sext <8 x i1> %cmp.i to <8 x i8>
> + %vmovl.i.i.i = zext <8 x i8> %vcgtz.i.i to <8 x i16>
> + ret <8 x i16> %vmovl.i.i.i
> +}
> <D2477.1.patch>_______________________________________________
> 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