diff options
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 8 | ||||
-rw-r--r-- | test/CodeGen/SystemZ/insert-06.ll | 13 |
2 files changed, 17 insertions, 4 deletions
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 4a5fb42..f6e1853 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1933,10 +1933,10 @@ SDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const { // high 32 bits and just masks out low bits. We can skip it if so. if (HighOp.getOpcode() == ISD::AND && HighOp.getOperand(1).getOpcode() == ISD::Constant) { - ConstantSDNode *MaskNode = cast<ConstantSDNode>(HighOp.getOperand(1)); - uint64_t Mask = MaskNode->getZExtValue() | Masks[High]; - if ((Mask >> 32) == 0xffffffff) - HighOp = HighOp.getOperand(0); + SDValue HighOp0 = HighOp.getOperand(0); + uint64_t Mask = cast<ConstantSDNode>(HighOp.getOperand(1))->getZExtValue(); + if (DAG.MaskedValueIsZero(HighOp0, APInt(64, ~(Mask | 0xffffffff)))) + HighOp = HighOp0; } // Take advantage of the fact that all GR32 operations only change the diff --git a/test/CodeGen/SystemZ/insert-06.ll b/test/CodeGen/SystemZ/insert-06.ll index 8366b2c..edcd0c5 100644 --- a/test/CodeGen/SystemZ/insert-06.ll +++ b/test/CodeGen/SystemZ/insert-06.ll @@ -165,3 +165,16 @@ define i64 @f13(i64 %a, i32 %b) { %or = or i64 %shift, %low ret i64 %or } + +; We previously wrongly removed the upper AND as dead. +define i64 @f14(i64 %a, i64 %b) { +; CHECK-LABEL: f14: +; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0 +; CHECK: br %r14 + %and1 = and i64 %a, 144115188075855872 + %and2 = and i64 %b, 15 + %or = or i64 %and1, %and2 + %res = icmp eq i64 %or, 0 + %ext = sext i1 %res to i64 + ret i64 %ext +} |