diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 333f0c17bacc5..5191360c7718a 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -2112,6 +2112,8 @@ bool CombinerHelper::matchCombineSubToAdd(MachineInstr &MI, MI.setDesc(B.getTII().get(TargetOpcode::G_ADD)); MI.getOperand(2).setReg(NegCst.getReg(0)); MI.clearFlag(MachineInstr::MIFlag::NoUWrap); + if (Imm.isMinSignedValue()) + MI.clearFlags(MachineInstr::MIFlag::NoSWrap); Observer.changedInstr(MI); }; return true; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir index 4c3faa9403909..de95527ceb1a2 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir @@ -551,3 +551,48 @@ body: | RET_ReallyLR implicit $w0 ... +--- +name: sub_to_add_nsw_128 +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sub_to_add_nsw_128 + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %a:_(s32) = COPY $w0 + ; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32) + ; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128 + ; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c + ; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8) + ; CHECK-NEXT: $w0 = COPY %d(s32) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %a:_(s32) = COPY $w0 + %b:_(s8) = G_TRUNC %a + %c:_(s8) = G_CONSTANT i8 -128 + %add:_(s8) = nsw nuw G_SUB %b, %c + %d:_(s32) = G_ZEXT %add + $w0 = COPY %d + RET_ReallyLR implicit $x0 + +... +--- +name: sub_to_add_nsw_intmin +body: | + bb.0: + liveins: $w0, $w1 + + ; CHECK-LABEL: name: sub_to_add_nsw_intmin + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: %a:_(s32) = COPY $w0 + ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648 + ; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c + ; CHECK-NEXT: $w0 = COPY %add(s32) + ; CHECK-NEXT: RET_ReallyLR implicit $x0 + %a:_(s32) = COPY $w0 + %c:_(s32) = G_CONSTANT i32 -2147483648 + %add:_(s32) = nsw nuw G_SUB %a, %c + $w0 = COPY %add + RET_ReallyLR implicit $x0 +... diff --git a/llvm/test/CodeGen/AArch64/sub1.ll b/llvm/test/CodeGen/AArch64/sub1.ll index 02893e2b63287..c359be57c27da 100644 --- a/llvm/test/CodeGen/AArch64/sub1.ll +++ b/llvm/test/CodeGen/AArch64/sub1.ll @@ -117,3 +117,17 @@ define <4 x i32> @masked_sub_v4i32(<4 x i32> %x) { %m = sub <4 x i32> , %a ret <4 x i32> %m } + +define i32 @pr137254(i32 %0) { +; CHECK-LABEL: pr137254: +; CHECK: // %bb.0: +; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000 +; CHECK-NEXT: add w8, w0, w8 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: cset w0, gt +; CHECK-NEXT: ret + %2 = sub nsw i32 %0, -2147483648 + %3 = icmp sgt i32 %2, 0 + %4 = select i1 %3, i32 1, i32 0 + ret i32 %4 +}