summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp6
-rw-r--r--llvm/test/CodeGen/SystemZ/int-const-02.ll17
2 files changed, 21 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index 802af1ae861..3073d2fcde1 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -1263,8 +1263,10 @@ void SystemZDAGToDAGISel::Select(SDNode *Node) {
// Fall through.
or_xor:
// If this is a 64-bit operation in which both 32-bit halves are nonzero,
- // split the operation into two.
- if (Node->getValueType(0) == MVT::i64)
+ // split the operation into two. If both operands here happen to be
+ // constant, leave this to common code to optimize.
+ if (Node->getValueType(0) == MVT::i64 &&
+ Node->getOperand(0).getOpcode() != ISD::Constant)
if (auto *Op1 = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
uint64_t Val = Op1->getZExtValue();
if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val)) {
diff --git a/llvm/test/CodeGen/SystemZ/int-const-02.ll b/llvm/test/CodeGen/SystemZ/int-const-02.ll
index e71abc69b3b..975fbf8698f 100644
--- a/llvm/test/CodeGen/SystemZ/int-const-02.ll
+++ b/llvm/test/CodeGen/SystemZ/int-const-02.ll
@@ -283,3 +283,20 @@ define i64 @f31() {
call void @foo(i64 32768, i64 65536, i64 4294967296, i64 281474976710656)
ret i64 42
}
+
+; Verify that we do not crash on OR with two constant inputs
+; (this was PR34859).
+define i64 @f32(i64 *%ptr) {
+; CHECK-LABEL: f32:
+; CHECK: llihf %r1, 918324340
+; CHECK: oilf %r1, 1806197964
+; CHECK: la %r0, 1(%r1)
+ store i64 -1, i64* %ptr, align 8
+ %1 = load i64, i64* %ptr, align 8
+ %2 = icmp ne i64 %1, 0
+ %3 = zext i1 %2 to i64
+ %4 = or i64 %3, 3944173009226982604
+ store i64 %4, i64* %ptr, align 8
+ ret i64 3944173009226982604
+}
+
OpenPOWER on IntegriCloud