Skip to content

Commit ec93ce5

Browse files
committed
[SCCP] Refine trunc with nsw/nuw flags
1 parent 0cbac99 commit ec93ce5

File tree

6 files changed

+42
-27
lines changed

6 files changed

+42
-27
lines changed

llvm/lib/Transforms/Utils/SCCPSolver.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,21 @@ static bool refineInstruction(SCCPSolver &Solver,
146146
Inst.setNonNeg();
147147
Changed = true;
148148
}
149+
} else if (TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
150+
auto Range = GetRange(Inst.getOperand(0));
151+
uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
152+
if (!TI->hasNoUnsignedWrap()) {
153+
if (Range.getActiveBits() <= DestWidth) {
154+
TI->setHasNoUnsignedWrap(true);
155+
Changed = true;
156+
}
157+
}
158+
if (!TI->hasNoSignedWrap()) {
159+
if (Range.getMinSignedBits() <= DestWidth) {
160+
TI->setHasNoSignedWrap(true);
161+
Changed = true;
162+
}
163+
}
149164
}
150165

151166
return Changed;

llvm/test/Transforms/PhaseOrdering/ARM/arm_mult_q15.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ define void @arm_mult_q15(ptr %pSrcA, ptr %pSrcB, ptr noalias %pDst, i32 %blockS
6969
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[CONV2]], [[CONV]]
7070
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[MUL]], 15
7171
; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = tail call i32 @llvm.smin.i32(i32 [[SHR]], i32 32767)
72-
; CHECK-NEXT: [[CONV3:%.*]] = trunc i32 [[SPEC_SELECT_I]] to i16
72+
; CHECK-NEXT: [[CONV3:%.*]] = trunc nsw i32 [[SPEC_SELECT_I]] to i16
7373
; CHECK-NEXT: [[INCDEC_PTR4]] = getelementptr inbounds i8, ptr [[PDST_ADDR_04]], i32 2
7474
; CHECK-NEXT: store i16 [[CONV3]], ptr [[PDST_ADDR_04]], align 2
7575
; CHECK-NEXT: [[DEC]] = add i32 [[BLKCNT_06]], -1

llvm/test/Transforms/SCCP/conditions-ranges.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ define i32 @f5(i64 %sz) {
178178
; CHECK-NEXT: br label [[COND_END]]
179179
; CHECK: cond.end:
180180
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
181-
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
181+
; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
182182
; CHECK-NEXT: ret i32 [[CONV]]
183183
;
184184
entry:
@@ -759,7 +759,7 @@ define i32 @udiv_1(i64 %sz) {
759759
; CHECK-NEXT: br label [[COND_END]]
760760
; CHECK: cond.end:
761761
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
762-
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
762+
; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
763763
; CHECK-NEXT: ret i32 [[CONV]]
764764
;
765765
entry:
@@ -786,7 +786,7 @@ define i32 @udiv_2(i64 %sz) {
786786
; CHECK-NEXT: br label [[COND_END]]
787787
; CHECK: cond.end:
788788
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ 0, [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
789-
; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
789+
; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
790790
; CHECK-NEXT: ret i32 [[CONV]]
791791
;
792792
entry:

llvm/test/Transforms/SCCP/ip-ranges-casts.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
; x = [100, 301)
55
define internal i1 @f.trunc(i32 %x) {
66
; CHECK-LABEL: @f.trunc(
7-
; CHECK-NEXT: [[T_1:%.*]] = trunc i32 [[X:%.*]] to i16
7+
; CHECK-NEXT: [[T_1:%.*]] = trunc nuw nsw i32 [[X:%.*]] to i16
88
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i16 [[T_1]], 299
99
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i16 [[T_1]], 101
1010
; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
@@ -329,7 +329,7 @@ define i64 @caller.sext_to_zext(i32 %i) {
329329
; CHECK-LABEL: @caller.sext_to_zext(
330330
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I:%.*]], 9
331331
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
332-
; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]])
332+
; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]]), !range [[RNG0:![0-9]+]]
333333
; CHECK-NEXT: ret i64 [[T]]
334334
;
335335
%cmp = icmp sle i32 %i, 9

llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define i16 @range_from_and_nuw(i32 %a) {
66
; CHECK-SAME: i32 [[A:%.*]]) {
77
; CHECK-NEXT: entry:
88
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 65535
9-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
9+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i32 [[AND1]] to i16
1010
; CHECK-NEXT: ret i16 [[TRUNC1]]
1111
;
1212
entry:
@@ -20,7 +20,7 @@ define i8 @range_from_or_nsw(i16 %a) {
2020
; CHECK-SAME: i16 [[A:%.*]]) {
2121
; CHECK-NEXT: entry:
2222
; CHECK-NEXT: [[AND1:%.*]] = or i16 [[A]], -128
23-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[AND1]] to i8
23+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i16 [[AND1]] to i8
2424
; CHECK-NEXT: ret i8 [[TRUNC1]]
2525
;
2626
entry:
@@ -34,7 +34,7 @@ define i16 @range_from_and_nuw_nsw(i32 %a) {
3434
; CHECK-SAME: i32 [[A:%.*]]) {
3535
; CHECK-NEXT: entry:
3636
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 32767
37-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
37+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw nsw i32 [[AND1]] to i16
3838
; CHECK-NEXT: ret i16 [[TRUNC1]]
3939
;
4040
entry:
@@ -67,8 +67,8 @@ define i4 @range_from_sge_sle(i8 %a) {
6767
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
6868
; CHECK: then:
6969
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[A]], 7
70-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i8 [[A]] to i4
71-
; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i8 [[AND1]] to i4
70+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i8 [[A]] to i4
71+
; CHECK-NEXT: [[TRUNC2:%.*]] = trunc nuw nsw i8 [[AND1]] to i4
7272
; CHECK-NEXT: [[XOR1:%.*]] = xor i4 [[TRUNC1]], [[TRUNC2]]
7373
; CHECK-NEXT: ret i4 [[XOR1]]
7474
; CHECK: else:
@@ -99,7 +99,7 @@ define i16 @range_from_sext(i16 %a) {
9999
; CHECK-SAME: i16 [[A:%.*]]) {
100100
; CHECK-NEXT: entry:
101101
; CHECK-NEXT: [[SEXT1:%.*]] = sext i16 [[A]] to i32
102-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[SEXT1]] to i16
102+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i32 [[SEXT1]] to i16
103103
; CHECK-NEXT: ret i16 [[TRUNC1]]
104104
;
105105
entry:
@@ -113,7 +113,7 @@ define i16 @range_from_zext(i16 %a) {
113113
; CHECK-SAME: i16 [[A:%.*]]) {
114114
; CHECK-NEXT: entry:
115115
; CHECK-NEXT: [[ZEXT1:%.*]] = zext i16 [[A]] to i32
116-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[ZEXT1]] to i16
116+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i32 [[ZEXT1]] to i16
117117
; CHECK-NEXT: ret i16 [[TRUNC1]]
118118
;
119119
entry:
@@ -127,7 +127,7 @@ define i1 @range_from_select_i1_nuw(i1 %c) {
127127
; CHECK-SAME: i1 [[C:%.*]]) {
128128
; CHECK-NEXT: entry:
129129
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 1
130-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
130+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i16 [[SELECT1]] to i1
131131
; CHECK-NEXT: ret i1 [[TRUNC1]]
132132
;
133133
entry:
@@ -141,7 +141,7 @@ define i1 @range_from_select_i1_nsw(i1 %c) {
141141
; CHECK-SAME: i1 [[C:%.*]]) {
142142
; CHECK-NEXT: entry:
143143
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 -1
144-
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
144+
; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i16 [[SELECT1]] to i1
145145
; CHECK-NEXT: ret i1 [[TRUNC1]]
146146
;
147147
entry:

llvm/test/Transforms/SCCP/widening.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ define void @foo(ptr %arg) {
438438
; SCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
439439
; SCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
440440
; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
441-
; SCCP-NEXT: i32 1, label [[BB3:%.*]]
442-
; SCCP-NEXT: i32 2, label [[BB4:%.*]]
443-
; SCCP-NEXT: i32 4, label [[BB19:%.*]]
441+
; SCCP-NEXT: i32 1, label [[BB3:%.*]]
442+
; SCCP-NEXT: i32 2, label [[BB4:%.*]]
443+
; SCCP-NEXT: i32 4, label [[BB19:%.*]]
444444
; SCCP-NEXT: ]
445445
; SCCP: bb3:
446446
; SCCP-NEXT: unreachable
@@ -449,7 +449,7 @@ define void @foo(ptr %arg) {
449449
; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
450450
; SCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
451451
; SCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
452-
; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
452+
; SCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
453453
; SCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
454454
; SCCP-NEXT: br label [[BB11:%.*]]
455455
; SCCP: bb11:
@@ -475,9 +475,9 @@ define void @foo(ptr %arg) {
475475
; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
476476
; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
477477
; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
478-
; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
479-
; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
480-
; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
478+
; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
479+
; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
480+
; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
481481
; IPSCCP-NEXT: ]
482482
; IPSCCP: bb3:
483483
; IPSCCP-NEXT: unreachable
@@ -486,7 +486,7 @@ define void @foo(ptr %arg) {
486486
; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
487487
; IPSCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
488488
; IPSCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
489-
; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
489+
; IPSCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
490490
; IPSCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
491491
; IPSCCP-NEXT: br label [[BB11:%.*]]
492492
; IPSCCP: bb11:
@@ -615,7 +615,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
615615
; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
616616
; SCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
617617
; SCCP: bb23:
618-
; SCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
618+
; SCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
619619
; SCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
620620
; SCCP-NEXT: br label [[BB31]]
621621
; SCCP: bb25:
@@ -639,7 +639,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
639639
; SCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
640640
; SCCP: bb39:
641641
; SCCP-NEXT: [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
642-
; SCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
642+
; SCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
643643
; SCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
644644
; SCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
645645
; SCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
@@ -697,7 +697,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
697697
; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
698698
; IPSCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
699699
; IPSCCP: bb23:
700-
; IPSCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
700+
; IPSCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
701701
; IPSCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
702702
; IPSCCP-NEXT: br label [[BB31]]
703703
; IPSCCP: bb25:
@@ -720,7 +720,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
720720
; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
721721
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
722722
; IPSCCP: bb39:
723-
; IPSCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
723+
; IPSCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
724724
; IPSCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
725725
; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7
726726
; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4

0 commit comments

Comments
 (0)