Index: llvm/lib/Target/AArch64/AArch64ISelLowering.h =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -535,6 +535,11 @@ const SelectionDAG &DAG, unsigned Depth = 0) const override; + unsigned ComputeNumSignBitsForTargetNode(SDValue Op, + const APInt &DemandedElts, + const SelectionDAG &DAG, + unsigned Depth) const override; + MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override { // Returning i64 unconditionally here (i.e. even for ILP32) means that the // *DAG* representation of pointers will always be 64-bits. They will be Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -2134,6 +2134,38 @@ } } +unsigned AArch64TargetLowering::ComputeNumSignBitsForTargetNode( + SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, + unsigned Depth) const { + EVT VT = Op.getValueType(); + unsigned VTBits = VT.getScalarSizeInBits(); + unsigned Opcode = Op.getOpcode(); + switch (Opcode) { + case AArch64ISD::CMEQ: + case AArch64ISD::CMGE: + case AArch64ISD::CMGT: + case AArch64ISD::CMHI: + case AArch64ISD::CMHS: + case AArch64ISD::FCMEQ: + case AArch64ISD::FCMGE: + case AArch64ISD::FCMGT: + case AArch64ISD::CMEQz: + case AArch64ISD::CMGEz: + case AArch64ISD::CMGTz: + case AArch64ISD::CMLEz: + case AArch64ISD::CMLTz: + case AArch64ISD::FCMEQz: + case AArch64ISD::FCMGEz: + case AArch64ISD::FCMGTz: + case AArch64ISD::FCMLEz: + case AArch64ISD::FCMLTz: + // Compares return either 0 or all-ones + return VTBits; + } + + return 1; +} + MVT AArch64TargetLowering::getScalarShiftAmountTy(const DataLayout &DL, EVT) const { return MVT::i64; Index: llvm/test/CodeGen/AArch64/cmp-select-sign.ll =================================================================== --- llvm/test/CodeGen/AArch64/cmp-select-sign.ll +++ llvm/test/CodeGen/AArch64/cmp-select-sign.ll @@ -71,7 +71,7 @@ define i64 @not_sign_i64(i64 %a) { ; CHECK-LABEL: not_sign_i64: ; CHECK: // %bb.0: -; CHECK-NEXT: mov w8, #1 +; CHECK-NEXT: mov w8, #1 // =0x1 ; CHECK-NEXT: cmp x0, #0 ; CHECK-NEXT: cneg x0, x8, le ; CHECK-NEXT: ret @@ -104,7 +104,7 @@ define i64 @not_sign_i64_4(i64 %a) { ; CHECK-LABEL: not_sign_i64_4: ; CHECK: // %bb.0: -; CHECK-NEXT: mov x0, #-1 +; CHECK-NEXT: mov x0, #-1 // =0xffffffffffffffff ; CHECK-NEXT: ret %c = icmp ugt i64 %a, -1 %res = select i1 %c, i64 1, i64 -1 @@ -229,10 +229,10 @@ ; CHECK: // %bb.0: ; CHECK-NEXT: movi v1.2d, #0xffffffffffffffff ; CHECK-NEXT: adrp x8, .LCPI18_0 -; CHECK-NEXT: movi v2.4s, #1 -; CHECK-NEXT: ldr q3, [x8, :lo12:.LCPI18_0] +; CHECK-NEXT: ldr q2, [x8, :lo12:.LCPI18_0] ; CHECK-NEXT: cmgt v0.4s, v0.4s, v1.4s -; CHECK-NEXT: bsl v0.16b, v2.16b, v3.16b +; CHECK-NEXT: bic v1.16b, v2.16b, v0.16b +; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s ; CHECK-NEXT: ret %c = icmp sgt <4 x i32> %a, %res = select <4 x i1> %c, <4 x i32> , <4 x i32>