[PATCH] Fix a bug in DAGcombiner about zero-extend after setcc.

Kevin Qin kevinqindev at gmail.com
Thu Dec 26 17:47:45 PST 2013


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
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2477.1.patch
Type: text/x-patch
Size: 1284 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131226/1eaf3b99/attachment.bin>


More information about the llvm-commits mailing list