Skip to content

Commit b9e3274

Browse files
authored
[GlobalISel] Clear nsw flags when converting sub to add. (#137288)
As shown in https://alive2.llvm.org/ce/z/PVwcTL we need to clear the nsw flags too when converting a sub to a add if the constant is INT_MIN. Fixes #137254
1 parent 5843069 commit b9e3274

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,6 +2112,8 @@ bool CombinerHelper::matchCombineSubToAdd(MachineInstr &MI,
21122112
MI.setDesc(B.getTII().get(TargetOpcode::G_ADD));
21132113
MI.getOperand(2).setReg(NegCst.getReg(0));
21142114
MI.clearFlag(MachineInstr::MIFlag::NoUWrap);
2115+
if (Imm.isMinSignedValue())
2116+
MI.clearFlags(MachineInstr::MIFlag::NoSWrap);
21152117
Observer.changedInstr(MI);
21162118
};
21172119
return true;

llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-trivial-arith.mir

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,48 @@ body: |
551551
RET_ReallyLR implicit $w0
552552
553553
...
554+
---
555+
name: sub_to_add_nsw_128
556+
body: |
557+
bb.0:
558+
liveins: $w0, $w1
559+
560+
; CHECK-LABEL: name: sub_to_add_nsw_128
561+
; CHECK: liveins: $w0, $w1
562+
; CHECK-NEXT: {{ $}}
563+
; CHECK-NEXT: %a:_(s32) = COPY $w0
564+
; CHECK-NEXT: %b:_(s8) = G_TRUNC %a(s32)
565+
; CHECK-NEXT: %c:_(s8) = G_CONSTANT i8 -128
566+
; CHECK-NEXT: %add:_(s8) = G_ADD %b, %c
567+
; CHECK-NEXT: %d:_(s32) = G_ZEXT %add(s8)
568+
; CHECK-NEXT: $w0 = COPY %d(s32)
569+
; CHECK-NEXT: RET_ReallyLR implicit $x0
570+
%a:_(s32) = COPY $w0
571+
%b:_(s8) = G_TRUNC %a
572+
%c:_(s8) = G_CONSTANT i8 -128
573+
%add:_(s8) = nsw nuw G_SUB %b, %c
574+
%d:_(s32) = G_ZEXT %add
575+
$w0 = COPY %d
576+
RET_ReallyLR implicit $x0
577+
578+
...
579+
---
580+
name: sub_to_add_nsw_intmin
581+
body: |
582+
bb.0:
583+
liveins: $w0, $w1
584+
585+
; CHECK-LABEL: name: sub_to_add_nsw_intmin
586+
; CHECK: liveins: $w0, $w1
587+
; CHECK-NEXT: {{ $}}
588+
; CHECK-NEXT: %a:_(s32) = COPY $w0
589+
; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 -2147483648
590+
; CHECK-NEXT: %add:_(s32) = G_ADD %a, %c
591+
; CHECK-NEXT: $w0 = COPY %add(s32)
592+
; CHECK-NEXT: RET_ReallyLR implicit $x0
593+
%a:_(s32) = COPY $w0
594+
%c:_(s32) = G_CONSTANT i32 -2147483648
595+
%add:_(s32) = nsw nuw G_SUB %a, %c
596+
$w0 = COPY %add
597+
RET_ReallyLR implicit $x0
598+
...

llvm/test/CodeGen/AArch64/sub1.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,17 @@ define <4 x i32> @masked_sub_v4i32(<4 x i32> %x) {
117117
%m = sub <4 x i32> <i32 511, i32 511, i32 511, i32 511>, %a
118118
ret <4 x i32> %m
119119
}
120+
121+
define i32 @pr137254(i32 %0) {
122+
; CHECK-LABEL: pr137254:
123+
; CHECK: // %bb.0:
124+
; CHECK-NEXT: mov w8, #-2147483648 // =0x80000000
125+
; CHECK-NEXT: add w8, w0, w8
126+
; CHECK-NEXT: cmp w8, #0
127+
; CHECK-NEXT: cset w0, gt
128+
; CHECK-NEXT: ret
129+
%2 = sub nsw i32 %0, -2147483648
130+
%3 = icmp sgt i32 %2, 0
131+
%4 = select i1 %3, i32 1, i32 0
132+
ret i32 %4
133+
}

0 commit comments

Comments
 (0)