[PATCH] D23570: Fix SystemZ compilation abort caused by negative AND mask
Elliot Colp via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 16 09:05:41 PDT 2016
colpell created this revision.
colpell added a reviewer: uweigand.
colpell added a subscriber: llvm-commits.
Normally, when an AND with a constant is lowered to NILL, the constant value is truncated to 16 bits. However, since r274066, ANDs whose results are used in a shift are caught by a different pattern that does not truncate. The instruction printer expects a 16-bit unsigned immediate operand for NILL, so this results in an abort.
This patch adds code to manually truncate the constant in this situation.
https://reviews.llvm.org/D23570
Files:
lib/Target/SystemZ/SystemZISelLowering.cpp
test/CodeGen/SystemZ/shift-11.ll
Index: test/CodeGen/SystemZ/shift-11.ll
===================================================================
--- test/CodeGen/SystemZ/shift-11.ll
+++ test/CodeGen/SystemZ/shift-11.ll
@@ -61,3 +61,25 @@
%shift = shl i64 %a, %and
ret i64 %shift
}
+
+; Test shift with negative 32-bit value.
+define i32 @f8(i32 %a, i32 %sh, i32 %test) {
+; CHECK-LABEL: f8:
+; CHECK: nill %r3, 65529
+; CHECK: sll %r2, 0(%r3)
+ %and = and i32 %sh, -7
+ %shift = shl i32 %a, %and
+
+ ret i32 %shift
+}
+
+; Test shift with negative 64-bit value.
+define i64 @f9(i64 %a, i64 %sh, i64 %test) {
+; CHECK-LABEL: f9:
+; CHECK: nill %r3, 65529
+; CHECK: sllg %r2, %r2, 0(%r3)
+ %and = and i64 %sh, -7
+ %shift = shl i64 %a, %and
+
+ ret i64 %shift
+}
Index: lib/Target/SystemZ/SystemZISelLowering.cpp
===================================================================
--- lib/Target/SystemZ/SystemZISelLowering.cpp
+++ lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -5072,12 +5072,12 @@
// value that has its last 6 bits set, we can safely remove the AND operation.
SDValue N1 = N->getOperand(1);
if (N1.getOpcode() == ISD::AND) {
- auto *AndMask = dyn_cast<ConstantSDNode>(N1.getOperand(1));
+ SDValue AndMaskOp = N1->getOperand(1);
+ auto *AndMask = dyn_cast<ConstantSDNode>(AndMaskOp);
+ auto AmtVal = AndMask->getZExtValue();
// The AND mask is constant
if (AndMask) {
- auto AmtVal = AndMask->getZExtValue();
-
// Bottom 6 bits are set
if ((AmtVal & 0x3f) == 0x3f) {
SDValue AndOp = N1->getOperand(0);
@@ -5099,6 +5099,25 @@
return Replace;
}
+
+ // We can't remove the AND, but we can use NILL here (normally we would
+ // use NILF). Only keep the last 16 bits of the mask.
+ } else if (AmtVal >> 16 != 0) {
+ SDValue AndOp = N1->getOperand(0);
+
+ auto NewMask = DAG.getConstant(AndMask->getZExtValue() & 0x0000ffff,
+ SDLoc(AndMaskOp),
+ AndMaskOp.getValueType());
+
+ auto NewAnd = DAG.getNode(N1.getOpcode(), SDLoc(N1), N1.getValueType(),
+ AndOp, NewMask);
+
+ SDValue Replace = DAG.getNode(N->getOpcode(), SDLoc(N),
+ N->getValueType(0), N->getOperand(0),
+ NewAnd);
+ DCI.AddToWorklist(Replace.getNode());
+
+ return Replace;
}
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23570.68196.patch
Type: text/x-patch
Size: 2469 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160816/ee414dfd/attachment.bin>
More information about the llvm-commits
mailing list