diff options
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/SystemZ/int-const-02.ll | 17 |
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 +} + |