Skip to content

Commit b109477

Browse files
authored
[InstCombine] Infer nsw/nuw for trunc (#87910)
This patch adds support for inferring trunc's nsw/nuw flags.
1 parent 9d9bb7b commit b109477

File tree

66 files changed

+309
-296
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+309
-296
lines changed

clang/test/CodeGen/ms-intrinsics-other.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 Mask)
8787
// CHECK: ret i8 [[RESULT]]
8888
// CHECK: [[ISNOTZERO_LABEL]]:
8989
// CHECK: [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true)
90-
// CHECK: [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32
90+
// CHECK: [[TRUNC_INDEX:%[0-9]+]] = trunc nuw nsw i64 [[INDEX]] to i32
9191
// CHECK: store i32 [[TRUNC_INDEX]], ptr %Index, align 4
9292
// CHECK: br label %[[END_LABEL]]
9393

@@ -102,7 +102,7 @@ unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask)
102102
// CHECK: ret i8 [[RESULT]]
103103
// CHECK: [[ISNOTZERO_LABEL]]:
104104
// CHECK: [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true)
105-
// CHECK: [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32
105+
// CHECK: [[TRUNC_REVINDEX:%[0-9]+]] = trunc nuw nsw i64 [[REVINDEX]] to i32
106106
// CHECK: [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63
107107
// CHECK: store i32 [[INDEX]], ptr %Index, align 4
108108
// CHECK: br label %[[END_LABEL]]

clang/test/CodeGen/ms-intrinsics.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ unsigned char test_BitScanForward64(unsigned long *Index, unsigned __int64 Mask)
189189
// CHECK-ARM-X64: ret i8 [[RESULT]]
190190
// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]:
191191
// CHECK-ARM-X64: [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true)
192-
// CHECK-ARM-X64: [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32
192+
// CHECK-ARM-X64: [[TRUNC_INDEX:%[0-9]+]] = trunc nuw nsw i64 [[INDEX]] to i32
193193
// CHECK-ARM-X64: store i32 [[TRUNC_INDEX]], ptr %Index, align 4
194194
// CHECK-ARM-X64: br label %[[END_LABEL]]
195195

@@ -204,7 +204,7 @@ unsigned char test_BitScanReverse64(unsigned long *Index, unsigned __int64 Mask)
204204
// CHECK-ARM-X64: ret i8 [[RESULT]]
205205
// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]:
206206
// CHECK-ARM-X64: [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true)
207-
// CHECK-ARM-X64: [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32
207+
// CHECK-ARM-X64: [[TRUNC_REVINDEX:%[0-9]+]] = trunc nuw nsw i64 [[REVINDEX]] to i32
208208
// CHECK-ARM-X64: [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63
209209
// CHECK-ARM-X64: store i32 [[INDEX]], ptr %Index, align 4
210210
// CHECK-ARM-X64: br label %[[END_LABEL]]

clang/test/CodeGenOpenCL/builtins-amdgcn.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ void test_read_exec_lo(global uint* out) {
528528
// CHECK-LABEL: @test_read_exec_hi(
529529
// CHECK: call i64 @llvm.amdgcn.ballot.i64(i1 true)
530530
// CHECK: lshr i64 [[A:%.*]], 32
531-
// CHECK: trunc i64 [[B:%.*]] to i32
531+
// CHECK: trunc nuw i64 [[B:%.*]] to i32
532532
void test_read_exec_hi(global uint* out) {
533533
*out = __builtin_amdgcn_read_exec_hi();
534534
}

clang/test/Headers/__clang_hip_math.hip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3703,7 +3703,7 @@ extern "C" __device__ BOOL_TYPE test___signbitf(float x) {
37033703
// CHECK-NEXT: entry:
37043704
// CHECK-NEXT: [[TMP0:%.*]] = bitcast double [[X:%.*]] to i64
37053705
// CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i64 [[TMP0]], 63
3706-
// CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[DOTLOBIT]] to i32
3706+
// CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[DOTLOBIT]] to i32
37073707
// CHECK-NEXT: ret i32 [[CONV]]
37083708
//
37093709
extern "C" __device__ BOOL_TYPE test___signbit(double x) {

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,20 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
897897
}
898898
}
899899

900-
return nullptr;
900+
bool Changed = false;
901+
if (!Trunc.hasNoSignedWrap() &&
902+
ComputeMaxSignificantBits(Src, /*Depth=*/0, &Trunc) <= DestWidth) {
903+
Trunc.setHasNoSignedWrap(true);
904+
Changed = true;
905+
}
906+
if (!Trunc.hasNoUnsignedWrap() &&
907+
MaskedValueIsZero(Src, APInt::getBitsSetFrom(SrcWidth, DestWidth),
908+
/*Depth=*/0, &Trunc)) {
909+
Trunc.setHasNoUnsignedWrap(true);
910+
Changed = true;
911+
}
912+
913+
return Changed ? &Trunc : nullptr;
901914
}
902915

903916
Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp,

llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvli-knownbits.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ entry:
4545
define signext i32 @vsetvl_sext() nounwind #0 {
4646
; CHECK-LABEL: @vsetvl_sext(
4747
; CHECK-NEXT: [[A:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 1, i64 1, i64 1)
48-
; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A]] to i32
48+
; CHECK-NEXT: [[B:%.*]] = trunc nuw nsw i64 [[A]] to i32
4949
; CHECK-NEXT: ret i32 [[B]]
5050
;
5151
%a = call i64 @llvm.riscv.vsetvli(i64 1, i64 1, i64 1)
@@ -56,7 +56,7 @@ define signext i32 @vsetvl_sext() nounwind #0 {
5656
define zeroext i32 @vsetvl_zext() nounwind #0 {
5757
; CHECK-LABEL: @vsetvl_zext(
5858
; CHECK-NEXT: [[A:%.*]] = call i64 @llvm.riscv.vsetvli.i64(i64 1, i64 1, i64 1)
59-
; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A]] to i32
59+
; CHECK-NEXT: [[B:%.*]] = trunc nuw nsw i64 [[A]] to i32
6060
; CHECK-NEXT: ret i32 [[B]]
6161
;
6262
%a = call i64 @llvm.riscv.vsetvli(i64 1, i64 1, i64 1)

llvm/test/Transforms/InstCombine/RISCV/riscv-vsetvlimax-knownbits.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ entry:
4545
define signext i32 @vsetvlmax_sext() nounwind #0 {
4646
; CHECK-LABEL: @vsetvlmax_sext(
4747
; CHECK-NEXT: [[A:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 1)
48-
; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A]] to i32
48+
; CHECK-NEXT: [[B:%.*]] = trunc nuw nsw i64 [[A]] to i32
4949
; CHECK-NEXT: ret i32 [[B]]
5050
;
5151
%a = call i64 @llvm.riscv.vsetvlimax(i64 1, i64 1)
@@ -56,7 +56,7 @@ define signext i32 @vsetvlmax_sext() nounwind #0 {
5656
define zeroext i32 @vsetvlmax_zext() nounwind #0 {
5757
; CHECK-LABEL: @vsetvlmax_zext(
5858
; CHECK-NEXT: [[A:%.*]] = call i64 @llvm.riscv.vsetvlimax.i64(i64 1, i64 1)
59-
; CHECK-NEXT: [[B:%.*]] = trunc i64 [[A]] to i32
59+
; CHECK-NEXT: [[B:%.*]] = trunc nuw nsw i64 [[A]] to i32
6060
; CHECK-NEXT: ret i32 [[B]]
6161
;
6262
%a = call i64 @llvm.riscv.vsetvlimax(i64 1, i64 1)

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2375,7 +2375,7 @@ define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64
23752375
; CHECK-NEXT: [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]
23762376
; CHECK-NEXT: [[T:%.*]] = trunc i128 [[SUB]] to i64
23772377
; CHECK-NEXT: [[TMP1:%.*]] = lshr i128 [[SUB]], 64
2378-
; CHECK-NEXT: [[DOTTR:%.*]] = trunc i128 [[TMP1]] to i64
2378+
; CHECK-NEXT: [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i64
23792379
; CHECK-NEXT: [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]]
23802380
; CHECK-NEXT: [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0
23812381
; CHECK-NEXT: [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 1

llvm/test/Transforms/InstCombine/binop-itofp.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ define float @test_ui_add_with_signed_constant(i32 %shr.i) {
10101010
define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345) {
10111011
; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul(
10121012
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1013-
; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
1013+
; CHECK-NEXT: [[CONV_I:%.*]] = trunc nuw i32 [[SEL]] to i16
10141014
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
10151015
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[CONV1_I]])
10161016
; CHECK-NEXT: store i32 [[SEL]], ptr [[G_2345:%.*]], align 4
@@ -1027,7 +1027,7 @@ define float @missed_nonzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g
10271027
define <2 x float> @missed_nonzero_check_on_constant_for_si_fmul_vec(i1 %c, i1 %.b, ptr %g_2345) {
10281028
; CHECK-LABEL: @missed_nonzero_check_on_constant_for_si_fmul_vec(
10291029
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1030-
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
1030+
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc nuw i32 [[SEL]] to i16
10311031
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
10321032
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
10331033
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
@@ -1048,7 +1048,7 @@ define <2 x float> @missed_nonzero_check_on_constant_for_si_fmul_vec(i1 %c, i1 %
10481048
define float @negzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345) {
10491049
; CHECK-LABEL: @negzero_check_on_constant_for_si_fmul(
10501050
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1051-
; CHECK-NEXT: [[CONV_I:%.*]] = trunc i32 [[SEL]] to i16
1051+
; CHECK-NEXT: [[CONV_I:%.*]] = trunc nuw i32 [[SEL]] to i16
10521052
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp i16 [[CONV_I]] to float
10531053
; CHECK-NEXT: [[TMP1:%.*]] = fneg float [[CONV1_I]]
10541054
; CHECK-NEXT: [[MUL3_I_I:%.*]] = call float @llvm.copysign.f32(float 0.000000e+00, float [[TMP1]])
@@ -1066,7 +1066,7 @@ define float @negzero_check_on_constant_for_si_fmul(i1 %c, i1 %.b, ptr %g_2345)
10661066
define <2 x float> @nonzero_check_on_constant_for_si_fmul_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
10671067
; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_vec_w_undef(
10681068
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1069-
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
1069+
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc nuw i32 [[SEL]] to i16
10701070
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
10711071
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
10721072
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
@@ -1087,7 +1087,7 @@ define <2 x float> @nonzero_check_on_constant_for_si_fmul_vec_w_undef(i1 %c, i1
10871087
define <2 x float> @nonzero_check_on_constant_for_si_fmul_nz_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
10881088
; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_nz_vec_w_undef(
10891089
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1090-
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
1090+
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc nuw i32 [[SEL]] to i16
10911091
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
10921092
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
10931093
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>
@@ -1108,7 +1108,7 @@ define <2 x float> @nonzero_check_on_constant_for_si_fmul_nz_vec_w_undef(i1 %c,
11081108
define <2 x float> @nonzero_check_on_constant_for_si_fmul_negz_vec_w_undef(i1 %c, i1 %.b, ptr %g_2345) {
11091109
; CHECK-LABEL: @nonzero_check_on_constant_for_si_fmul_negz_vec_w_undef(
11101110
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i32 65529, i32 53264
1111-
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc i32 [[SEL]] to i16
1111+
; CHECK-NEXT: [[CONV_I_S:%.*]] = trunc nuw i32 [[SEL]] to i16
11121112
; CHECK-NEXT: [[CONV_I_V:%.*]] = insertelement <2 x i16> poison, i16 [[CONV_I_S]], i64 0
11131113
; CHECK-NEXT: [[CONV_I:%.*]] = shufflevector <2 x i16> [[CONV_I_V]], <2 x i16> poison, <2 x i32> zeroinitializer
11141114
; CHECK-NEXT: [[CONV1_I:%.*]] = sitofp <2 x i16> [[CONV_I]] to <2 x float>

llvm/test/Transforms/InstCombine/bswap-fold.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ define i64 @variable_shl_not_masked_enough_i64(i64 %x, i64 %n) {
211211
define i16 @test7(i32 %A) {
212212
; CHECK-LABEL: @test7(
213213
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[A:%.*]], 16
214-
; CHECK-NEXT: [[D:%.*]] = trunc i32 [[TMP1]] to i16
214+
; CHECK-NEXT: [[D:%.*]] = trunc nuw i32 [[TMP1]] to i16
215215
; CHECK-NEXT: ret i16 [[D]]
216216
;
217217
%B = tail call i32 @llvm.bswap.i32(i32 %A) nounwind
@@ -223,7 +223,7 @@ define i16 @test7(i32 %A) {
223223
define <2 x i16> @test7_vector(<2 x i32> %A) {
224224
; CHECK-LABEL: @test7_vector(
225225
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 16, i32 16>
226-
; CHECK-NEXT: [[D:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
226+
; CHECK-NEXT: [[D:%.*]] = trunc nuw <2 x i32> [[TMP1]] to <2 x i16>
227227
; CHECK-NEXT: ret <2 x i16> [[D]]
228228
;
229229
%B = tail call <2 x i32> @llvm.bswap.v2i32(<2 x i32> %A) nounwind
@@ -235,7 +235,7 @@ define <2 x i16> @test7_vector(<2 x i32> %A) {
235235
define i16 @test8(i64 %A) {
236236
; CHECK-LABEL: @test8(
237237
; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[A:%.*]], 48
238-
; CHECK-NEXT: [[D:%.*]] = trunc i64 [[TMP1]] to i16
238+
; CHECK-NEXT: [[D:%.*]] = trunc nuw i64 [[TMP1]] to i16
239239
; CHECK-NEXT: ret i16 [[D]]
240240
;
241241
%B = tail call i64 @llvm.bswap.i64(i64 %A) nounwind
@@ -247,7 +247,7 @@ define i16 @test8(i64 %A) {
247247
define <2 x i16> @test8_vector(<2 x i64> %A) {
248248
; CHECK-LABEL: @test8_vector(
249249
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i64> [[A:%.*]], <i64 48, i64 48>
250-
; CHECK-NEXT: [[D:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i16>
250+
; CHECK-NEXT: [[D:%.*]] = trunc nuw <2 x i64> [[TMP1]] to <2 x i16>
251251
; CHECK-NEXT: ret <2 x i16> [[D]]
252252
;
253253
%B = tail call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %A) nounwind

0 commit comments

Comments
 (0)