diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 8ea3a03b1b4ab..21bdb2fbf6e56 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -7394,8 +7394,10 @@ static bool canCreateUndefOrPoison(const Operator *Op, UndefPoisonKind Kind, case Intrinsic::fshr: case Intrinsic::smax: case Intrinsic::smin: + case Intrinsic::scmp: case Intrinsic::umax: case Intrinsic::umin: + case Intrinsic::ucmp: case Intrinsic::ptrmask: case Intrinsic::fptoui_sat: case Intrinsic::fptosi_sat: diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index 8955dd0370539..e41fd81953f43 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -1869,8 +1869,10 @@ static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI, case TargetOpcode::G_FSHR: case TargetOpcode::G_SMAX: case TargetOpcode::G_SMIN: + case TargetOpcode::G_SCMP: case TargetOpcode::G_UMAX: case TargetOpcode::G_UMIN: + case TargetOpcode::G_UCMP: case TargetOpcode::G_PTRMASK: case TargetOpcode::G_SADDO: case TargetOpcode::G_SSUBO: diff --git a/llvm/test/CodeGen/AArch64/freeze.ll b/llvm/test/CodeGen/AArch64/freeze.ll index d428b6aa483a7..36d88c5524932 100644 --- a/llvm/test/CodeGen/AArch64/freeze.ll +++ b/llvm/test/CodeGen/AArch64/freeze.ll @@ -429,3 +429,37 @@ define <8 x i16> @freeze_abds(<8 x i16> %a, <8 x i16> %b) { %r = add <8 x i16> %a, %f ret <8 x i16> %r } + +define i32 @freeze_scmp(i32 %a0) nounwind { +; CHECK-LABEL: freeze_scmp: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #2 // =0x2 +; CHECK-NEXT: cmp w8, w0 +; CHECK-NEXT: cset w8, gt +; CHECK-NEXT: csinv w8, w8, wzr, ge +; CHECK-NEXT: cmp wzr, w8 +; CHECK-NEXT: cset w8, gt +; CHECK-NEXT: csinv w0, w8, wzr, ge +; CHECK-NEXT: ret + %x = call i32 @llvm.scmp.i32(i32 2, i32 %a0) + %y = freeze i32 %x + %z = call i32 @llvm.scmp.i32(i32 0, i32 %y) + ret i32 %z +} + +define i32 @freeze_ucmp(i32 %a0) nounwind { +; CHECK-LABEL: freeze_ucmp: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #2 // =0x2 +; CHECK-NEXT: cmp w8, w0 +; CHECK-NEXT: cset w8, hi +; CHECK-NEXT: csinv w8, w8, wzr, hs +; CHECK-NEXT: cmp w8, #1 +; CHECK-NEXT: cset w8, hi +; CHECK-NEXT: csinv w0, w8, wzr, hs +; CHECK-NEXT: ret + %x = call i32 @llvm.ucmp.i32(i32 2, i32 %a0) + %y = freeze i32 %x + %z = call i32 @llvm.ucmp.i32(i32 %y, i32 1) + ret i32 %z +} diff --git a/llvm/test/Transforms/InstCombine/freeze-integer-intrinsics.ll b/llvm/test/Transforms/InstCombine/freeze-integer-intrinsics.ll index c4a590e1a12bf..3cab09c2876bf 100644 --- a/llvm/test/Transforms/InstCombine/freeze-integer-intrinsics.ll +++ b/llvm/test/Transforms/InstCombine/freeze-integer-intrinsics.ll @@ -426,6 +426,32 @@ define i1 @widenable_condition() { ret i1 %freeze } +define i32 @freeze_scmp(i32 %a0) { +; CHECK-LABEL: @freeze_scmp( +; CHECK-NEXT: [[A0_FR:%.*]] = freeze i32 [[A0:%.*]] +; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.scmp.i32.i32(i32 2, i32 [[A0_FR]]) +; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.scmp.i32.i32(i32 0, i32 [[X]]) +; CHECK-NEXT: ret i32 [[Z]] +; + %x = call i32 @llvm.scmp.i32(i32 2, i32 %a0) + %y = freeze i32 %x + %z = call i32 @llvm.scmp.i32(i32 0, i32 %y) + ret i32 %z +} + +define i32 @freeze_ucmp(i32 %a0) { +; CHECK-LABEL: @freeze_ucmp( +; CHECK-NEXT: [[A0_FR:%.*]] = freeze i32 [[A0:%.*]] +; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.ucmp.i32.i32(i32 2, i32 [[A0_FR]]) +; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.ucmp.i32.i32(i32 [[X]], i32 1) +; CHECK-NEXT: ret i32 [[Z]] +; + %x = call i32 @llvm.ucmp.i32(i32 2, i32 %a0) + %y = freeze i32 %x + %z = call i32 @llvm.ucmp.i32(i32 %y, i32 1) + ret i32 %z +} + declare i32 @llvm.ctlz.i32(i32, i1 immarg) declare i32 @llvm.cttz.i32(i32, i1 immarg) declare i32 @llvm.abs.i32(i32, i1 immarg)