[llvm] [SCCP] Refine trunc with nsw/nuw flags (PR #87926)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 7 08:00:32 PDT 2024
https://github.com/XChy updated https://github.com/llvm/llvm-project/pull/87926
>From d76f7960890a25b4d34e5a7fe351fdb2c85a2a36 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 7 Apr 2024 21:47:30 +0800
Subject: [PATCH 1/3] [SCCP][NFC] Precommit tests
---
.../Transforms/SCCP/trunc-nuw-nsw-flags.ll | 179 ++++++++++++++++++
1 file changed, 179 insertions(+)
create mode 100644 llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
diff --git a/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll b/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
new file mode 100644
index 00000000000000..0447c82bb55421
--- /dev/null
+++ b/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
@@ -0,0 +1,179 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -passes=ipsccp -S %s | FileCheck %s
+
+define i16 @range_from_and_nuw(i32 %a) {
+; CHECK-LABEL: define i16 @range_from_and_nuw(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 65535
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
+; CHECK-NEXT: ret i16 [[TRUNC1]]
+;
+entry:
+ %and1 = and i32 %a, 65535
+ %trunc1 = trunc i32 %and1 to i16
+ ret i16 %trunc1
+}
+
+define i8 @range_from_or_nsw(i16 %a) {
+; CHECK-LABEL: define i8 @range_from_or_nsw(
+; CHECK-SAME: i16 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = or i16 [[A]], -128
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[AND1]] to i8
+; CHECK-NEXT: ret i8 [[TRUNC1]]
+;
+entry:
+ %and1 = or i16 %a, 65408
+ %trunc1 = trunc i16 %and1 to i8
+ ret i8 %trunc1
+}
+
+define i16 @range_from_and_nuw_nsw(i32 %a) {
+; CHECK-LABEL: define i16 @range_from_and_nuw_nsw(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 32767
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
+; CHECK-NEXT: ret i16 [[TRUNC1]]
+;
+entry:
+ %and1 = and i32 %a, 32767
+ %trunc1 = trunc i32 %and1 to i16
+ ret i16 %trunc1
+}
+
+define <4 x i16> @range_from_and_nuw_vec(<4 x i32> %a) {
+; CHECK-LABEL: define <4 x i16> @range_from_and_nuw_vec(
+; CHECK-SAME: <4 x i32> [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[A]], <i32 65535, i32 65535, i32 65535, i32 65535>
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc <4 x i32> [[AND1]] to <4 x i16>
+; CHECK-NEXT: ret <4 x i16> [[TRUNC1]]
+;
+entry:
+ %and1 = and <4 x i32> %a, <i32 65535, i32 65535, i32 65535, i32 65535>
+ %trunc1 = trunc <4 x i32> %and1 to <4 x i16>
+ ret <4 x i16> %trunc1
+}
+
+define i4 @range_from_sge_sle(i8 %a) {
+; CHECK-LABEL: define i4 @range_from_sge_sle(
+; CHECK-SAME: i8 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SGT:%.*]] = icmp sge i8 [[A]], 0
+; CHECK-NEXT: [[SLT:%.*]] = icmp sle i8 [[A]], 15
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[SGT]], [[SLT]]
+; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[AND1:%.*]] = and i8 [[A]], 7
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i8 [[A]] to i4
+; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i8 [[AND1]] to i4
+; CHECK-NEXT: [[XOR1:%.*]] = xor i4 [[TRUNC1]], [[TRUNC2]]
+; CHECK-NEXT: ret i4 [[XOR1]]
+; CHECK: else:
+; CHECK-NEXT: [[TRUNC3:%.*]] = trunc i8 [[A]] to i4
+; CHECK-NEXT: ret i4 [[TRUNC3]]
+;
+entry:
+ %sgt = icmp sge i8 %a, 0
+ %slt = icmp sle i8 %a, 15
+ %and = and i1 %sgt, %slt
+ br i1 %and, label %then, label %else
+
+then:
+ %and1 = and i8 %a, 7
+
+ %trunc1 = trunc i8 %a to i4
+ %trunc2 = trunc i8 %and1 to i4
+ %xor1 = xor i4 %trunc1, %trunc2
+ ret i4 %xor1
+
+else:
+ %trunc3 = trunc i8 %a to i4
+ ret i4 %trunc3
+}
+
+define i16 @range_from_sext(i16 %a) {
+; CHECK-LABEL: define i16 @range_from_sext(
+; CHECK-SAME: i16 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SEXT1:%.*]] = sext i16 [[A]] to i32
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[SEXT1]] to i16
+; CHECK-NEXT: ret i16 [[TRUNC1]]
+;
+entry:
+ %sext1 = sext i16 %a to i32
+ %trunc1 = trunc i32 %sext1 to i16
+ ret i16 %trunc1
+}
+
+define i16 @range_from_zext(i16 %a) {
+; CHECK-LABEL: define i16 @range_from_zext(
+; CHECK-SAME: i16 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ZEXT1:%.*]] = zext i16 [[A]] to i32
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[ZEXT1]] to i16
+; CHECK-NEXT: ret i16 [[TRUNC1]]
+;
+entry:
+ %zext1 = zext i16 %a to i32
+ %trunc1 = trunc i32 %zext1 to i16
+ ret i16 %trunc1
+}
+
+define i1 @range_from_select_i1_nuw(i1 %c) {
+; CHECK-LABEL: define i1 @range_from_select_i1_nuw(
+; CHECK-SAME: i1 [[C:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 1
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC1]]
+;
+entry:
+ %select1 = select i1 %c, i16 0, i16 1
+ %trunc1 = trunc i16 %select1 to i1
+ ret i1 %trunc1
+}
+
+define i1 @range_from_select_i1_nsw(i1 %c) {
+; CHECK-LABEL: define i1 @range_from_select_i1_nsw(
+; CHECK-SAME: i1 [[C:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 -1
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC1]]
+;
+entry:
+ %select1 = select i1 %c, i16 0, i16 -1
+ %trunc1 = trunc i16 %select1 to i1
+ ret i1 %trunc1
+}
+
+define i1 @range_from_select_i1_fail(i1 %c) {
+; CHECK-LABEL: define i1 @range_from_select_i1_fail(
+; CHECK-SAME: i1 [[C:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 1, i16 -1
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
+; CHECK-NEXT: ret i1 [[TRUNC1]]
+;
+entry:
+ %select1 = select i1 %c, i16 1, i16 -1
+ %trunc1 = trunc i16 %select1 to i1
+ ret i1 %trunc1
+}
+
+define i8 @range_from_trunc_fail(i32 %a) {
+; CHECK-LABEL: define i8 @range_from_trunc_fail(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[A]] to i16
+; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i16 [[TRUNC1]] to i8
+; CHECK-NEXT: ret i8 [[TRUNC2]]
+;
+entry:
+ %trunc1 = trunc i32 %a to i16
+ %trunc2 = trunc i16 %trunc1 to i8
+ ret i8 %trunc2
+}
>From 333b33934a0f7f901a38e1f5fb44a12eeab95b9c Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 7 Apr 2024 19:28:48 +0800
Subject: [PATCH 2/3] [SCCP] Refine trunc with nsw/nuw flags
---
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 15 +++++
.../PhaseOrdering/AArch64/quant_4x4.ll | 64 +++++++++----------
.../PhaseOrdering/ARM/arm_mult_q15.ll | 2 +-
.../test/Transforms/SCCP/conditions-ranges.ll | 6 +-
llvm/test/Transforms/SCCP/ip-ranges-casts.ll | 4 +-
.../Transforms/SCCP/trunc-nuw-nsw-flags.ll | 18 +++---
llvm/test/Transforms/SCCP/widening.ll | 24 +++----
7 files changed, 74 insertions(+), 59 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 38fc7763c5b204..3cec6623df33ec 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -146,6 +146,21 @@ static bool refineInstruction(SCCPSolver &Solver,
Inst.setNonNeg();
Changed = true;
}
+ } else if (TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
+ auto Range = GetRange(Inst.getOperand(0));
+ uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
+ if (!TI->hasNoUnsignedWrap()) {
+ if (Range.getActiveBits() <= DestWidth) {
+ TI->setHasNoUnsignedWrap(true);
+ Changed = true;
+ }
+ }
+ if (!TI->hasNoSignedWrap()) {
+ if (Range.getMinSignedBits() <= DestWidth) {
+ TI->setHasNoSignedWrap(true);
+ Changed = true;
+ }
+ }
}
return Changed;
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/quant_4x4.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/quant_4x4.ll
index d18b207e87076b..488c700ff98ffd 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/quant_4x4.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/quant_4x4.ll
@@ -83,13 +83,13 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CONV5]], [[CONV]]
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ADD]], [[CONV11]]
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[MUL]], 16
-; CHECK-NEXT: [[CONV12:%.*]] = trunc i32 [[SHR]] to i16
+; CHECK-NEXT: [[CONV12:%.*]] = trunc nuw i32 [[SHR]] to i16
; CHECK-NEXT: br label [[IF_END:%.*]]
; CHECK: if.else:
; CHECK-NEXT: [[ADD21:%.*]] = sub nsw i32 [[CONV5]], [[CONV]]
; CHECK-NEXT: [[MUL25:%.*]] = mul i32 [[ADD21]], [[CONV11]]
; CHECK-NEXT: [[SHR26:%.*]] = lshr i32 [[MUL25]], 16
-; CHECK-NEXT: [[TMP33:%.*]] = trunc i32 [[SHR26]] to i16
+; CHECK-NEXT: [[TMP33:%.*]] = trunc nuw i32 [[SHR26]] to i16
; CHECK-NEXT: [[CONV28:%.*]] = sub i16 0, [[TMP33]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
@@ -110,14 +110,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_1:%.*]] = sub nsw i32 [[CONV5_1]], [[CONV_1]]
; CHECK-NEXT: [[MUL25_1:%.*]] = mul i32 [[ADD21_1]], [[CONV11_1]]
; CHECK-NEXT: [[SHR26_1:%.*]] = lshr i32 [[MUL25_1]], 16
-; CHECK-NEXT: [[TMP37:%.*]] = trunc i32 [[SHR26_1]] to i16
+; CHECK-NEXT: [[TMP37:%.*]] = trunc nuw i32 [[SHR26_1]] to i16
; CHECK-NEXT: [[CONV28_1:%.*]] = sub i16 0, [[TMP37]]
; CHECK-NEXT: br label [[IF_END_1:%.*]]
; CHECK: if.then.1:
; CHECK-NEXT: [[ADD_1:%.*]] = add nuw nsw i32 [[CONV5_1]], [[CONV_1]]
; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[ADD_1]], [[CONV11_1]]
; CHECK-NEXT: [[SHR_1:%.*]] = lshr i32 [[MUL_1]], 16
-; CHECK-NEXT: [[CONV12_1:%.*]] = trunc i32 [[SHR_1]] to i16
+; CHECK-NEXT: [[CONV12_1:%.*]] = trunc nuw i32 [[SHR_1]] to i16
; CHECK-NEXT: br label [[IF_END_1]]
; CHECK: if.end.1:
; CHECK-NEXT: [[STOREMERGE_1:%.*]] = phi i16 [ [[CONV28_1]], [[IF_ELSE_1]] ], [ [[CONV12_1]], [[IF_THEN_1]] ]
@@ -138,14 +138,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_2:%.*]] = sub nsw i32 [[CONV5_2]], [[CONV_2]]
; CHECK-NEXT: [[MUL25_2:%.*]] = mul i32 [[ADD21_2]], [[CONV11_2]]
; CHECK-NEXT: [[SHR26_2:%.*]] = lshr i32 [[MUL25_2]], 16
-; CHECK-NEXT: [[TMP41:%.*]] = trunc i32 [[SHR26_2]] to i16
+; CHECK-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[SHR26_2]] to i16
; CHECK-NEXT: [[CONV28_2:%.*]] = sub i16 0, [[TMP41]]
; CHECK-NEXT: br label [[IF_END_2:%.*]]
; CHECK: if.then.2:
; CHECK-NEXT: [[ADD_2:%.*]] = add nuw nsw i32 [[CONV5_2]], [[CONV_2]]
; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[ADD_2]], [[CONV11_2]]
; CHECK-NEXT: [[SHR_2:%.*]] = lshr i32 [[MUL_2]], 16
-; CHECK-NEXT: [[CONV12_2:%.*]] = trunc i32 [[SHR_2]] to i16
+; CHECK-NEXT: [[CONV12_2:%.*]] = trunc nuw i32 [[SHR_2]] to i16
; CHECK-NEXT: br label [[IF_END_2]]
; CHECK: if.end.2:
; CHECK-NEXT: [[STOREMERGE_2:%.*]] = phi i16 [ [[CONV28_2]], [[IF_ELSE_2]] ], [ [[CONV12_2]], [[IF_THEN_2]] ]
@@ -166,14 +166,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_3:%.*]] = sub nsw i32 [[CONV5_3]], [[CONV_3]]
; CHECK-NEXT: [[MUL25_3:%.*]] = mul i32 [[ADD21_3]], [[CONV11_3]]
; CHECK-NEXT: [[SHR26_3:%.*]] = lshr i32 [[MUL25_3]], 16
-; CHECK-NEXT: [[TMP45:%.*]] = trunc i32 [[SHR26_3]] to i16
+; CHECK-NEXT: [[TMP45:%.*]] = trunc nuw i32 [[SHR26_3]] to i16
; CHECK-NEXT: [[CONV28_3:%.*]] = sub i16 0, [[TMP45]]
; CHECK-NEXT: br label [[IF_END_3:%.*]]
; CHECK: if.then.3:
; CHECK-NEXT: [[ADD_3:%.*]] = add nuw nsw i32 [[CONV5_3]], [[CONV_3]]
; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[ADD_3]], [[CONV11_3]]
; CHECK-NEXT: [[SHR_3:%.*]] = lshr i32 [[MUL_3]], 16
-; CHECK-NEXT: [[CONV12_3:%.*]] = trunc i32 [[SHR_3]] to i16
+; CHECK-NEXT: [[CONV12_3:%.*]] = trunc nuw i32 [[SHR_3]] to i16
; CHECK-NEXT: br label [[IF_END_3]]
; CHECK: if.end.3:
; CHECK-NEXT: [[STOREMERGE_3:%.*]] = phi i16 [ [[CONV28_3]], [[IF_ELSE_3]] ], [ [[CONV12_3]], [[IF_THEN_3]] ]
@@ -194,14 +194,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_4:%.*]] = sub nsw i32 [[CONV5_4]], [[CONV_4]]
; CHECK-NEXT: [[MUL25_4:%.*]] = mul i32 [[ADD21_4]], [[CONV11_4]]
; CHECK-NEXT: [[SHR26_4:%.*]] = lshr i32 [[MUL25_4]], 16
-; CHECK-NEXT: [[TMP49:%.*]] = trunc i32 [[SHR26_4]] to i16
+; CHECK-NEXT: [[TMP49:%.*]] = trunc nuw i32 [[SHR26_4]] to i16
; CHECK-NEXT: [[CONV28_4:%.*]] = sub i16 0, [[TMP49]]
; CHECK-NEXT: br label [[IF_END_4:%.*]]
; CHECK: if.then.4:
; CHECK-NEXT: [[ADD_4:%.*]] = add nuw nsw i32 [[CONV5_4]], [[CONV_4]]
; CHECK-NEXT: [[MUL_4:%.*]] = mul i32 [[ADD_4]], [[CONV11_4]]
; CHECK-NEXT: [[SHR_4:%.*]] = lshr i32 [[MUL_4]], 16
-; CHECK-NEXT: [[CONV12_4:%.*]] = trunc i32 [[SHR_4]] to i16
+; CHECK-NEXT: [[CONV12_4:%.*]] = trunc nuw i32 [[SHR_4]] to i16
; CHECK-NEXT: br label [[IF_END_4]]
; CHECK: if.end.4:
; CHECK-NEXT: [[STOREMERGE_4:%.*]] = phi i16 [ [[CONV28_4]], [[IF_ELSE_4]] ], [ [[CONV12_4]], [[IF_THEN_4]] ]
@@ -222,14 +222,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_5:%.*]] = sub nsw i32 [[CONV5_5]], [[CONV_5]]
; CHECK-NEXT: [[MUL25_5:%.*]] = mul i32 [[ADD21_5]], [[CONV11_5]]
; CHECK-NEXT: [[SHR26_5:%.*]] = lshr i32 [[MUL25_5]], 16
-; CHECK-NEXT: [[TMP53:%.*]] = trunc i32 [[SHR26_5]] to i16
+; CHECK-NEXT: [[TMP53:%.*]] = trunc nuw i32 [[SHR26_5]] to i16
; CHECK-NEXT: [[CONV28_5:%.*]] = sub i16 0, [[TMP53]]
; CHECK-NEXT: br label [[IF_END_5:%.*]]
; CHECK: if.then.5:
; CHECK-NEXT: [[ADD_5:%.*]] = add nuw nsw i32 [[CONV5_5]], [[CONV_5]]
; CHECK-NEXT: [[MUL_5:%.*]] = mul i32 [[ADD_5]], [[CONV11_5]]
; CHECK-NEXT: [[SHR_5:%.*]] = lshr i32 [[MUL_5]], 16
-; CHECK-NEXT: [[CONV12_5:%.*]] = trunc i32 [[SHR_5]] to i16
+; CHECK-NEXT: [[CONV12_5:%.*]] = trunc nuw i32 [[SHR_5]] to i16
; CHECK-NEXT: br label [[IF_END_5]]
; CHECK: if.end.5:
; CHECK-NEXT: [[STOREMERGE_5:%.*]] = phi i16 [ [[CONV28_5]], [[IF_ELSE_5]] ], [ [[CONV12_5]], [[IF_THEN_5]] ]
@@ -250,14 +250,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_6:%.*]] = sub nsw i32 [[CONV5_6]], [[CONV_6]]
; CHECK-NEXT: [[MUL25_6:%.*]] = mul i32 [[ADD21_6]], [[CONV11_6]]
; CHECK-NEXT: [[SHR26_6:%.*]] = lshr i32 [[MUL25_6]], 16
-; CHECK-NEXT: [[TMP57:%.*]] = trunc i32 [[SHR26_6]] to i16
+; CHECK-NEXT: [[TMP57:%.*]] = trunc nuw i32 [[SHR26_6]] to i16
; CHECK-NEXT: [[CONV28_6:%.*]] = sub i16 0, [[TMP57]]
; CHECK-NEXT: br label [[IF_END_6:%.*]]
; CHECK: if.then.6:
; CHECK-NEXT: [[ADD_6:%.*]] = add nuw nsw i32 [[CONV5_6]], [[CONV_6]]
; CHECK-NEXT: [[MUL_6:%.*]] = mul i32 [[ADD_6]], [[CONV11_6]]
; CHECK-NEXT: [[SHR_6:%.*]] = lshr i32 [[MUL_6]], 16
-; CHECK-NEXT: [[CONV12_6:%.*]] = trunc i32 [[SHR_6]] to i16
+; CHECK-NEXT: [[CONV12_6:%.*]] = trunc nuw i32 [[SHR_6]] to i16
; CHECK-NEXT: br label [[IF_END_6]]
; CHECK: if.end.6:
; CHECK-NEXT: [[STOREMERGE_6:%.*]] = phi i16 [ [[CONV28_6]], [[IF_ELSE_6]] ], [ [[CONV12_6]], [[IF_THEN_6]] ]
@@ -278,14 +278,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_7:%.*]] = sub nsw i32 [[CONV5_7]], [[CONV_7]]
; CHECK-NEXT: [[MUL25_7:%.*]] = mul i32 [[ADD21_7]], [[CONV11_7]]
; CHECK-NEXT: [[SHR26_7:%.*]] = lshr i32 [[MUL25_7]], 16
-; CHECK-NEXT: [[TMP61:%.*]] = trunc i32 [[SHR26_7]] to i16
+; CHECK-NEXT: [[TMP61:%.*]] = trunc nuw i32 [[SHR26_7]] to i16
; CHECK-NEXT: [[CONV28_7:%.*]] = sub i16 0, [[TMP61]]
; CHECK-NEXT: br label [[IF_END_7:%.*]]
; CHECK: if.then.7:
; CHECK-NEXT: [[ADD_7:%.*]] = add nuw nsw i32 [[CONV5_7]], [[CONV_7]]
; CHECK-NEXT: [[MUL_7:%.*]] = mul i32 [[ADD_7]], [[CONV11_7]]
; CHECK-NEXT: [[SHR_7:%.*]] = lshr i32 [[MUL_7]], 16
-; CHECK-NEXT: [[CONV12_7:%.*]] = trunc i32 [[SHR_7]] to i16
+; CHECK-NEXT: [[CONV12_7:%.*]] = trunc nuw i32 [[SHR_7]] to i16
; CHECK-NEXT: br label [[IF_END_7]]
; CHECK: if.end.7:
; CHECK-NEXT: [[STOREMERGE_7:%.*]] = phi i16 [ [[CONV28_7]], [[IF_ELSE_7]] ], [ [[CONV12_7]], [[IF_THEN_7]] ]
@@ -306,14 +306,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_8:%.*]] = sub nsw i32 [[CONV5_8]], [[CONV_8]]
; CHECK-NEXT: [[MUL25_8:%.*]] = mul i32 [[ADD21_8]], [[CONV11_8]]
; CHECK-NEXT: [[SHR26_8:%.*]] = lshr i32 [[MUL25_8]], 16
-; CHECK-NEXT: [[TMP65:%.*]] = trunc i32 [[SHR26_8]] to i16
+; CHECK-NEXT: [[TMP65:%.*]] = trunc nuw i32 [[SHR26_8]] to i16
; CHECK-NEXT: [[CONV28_8:%.*]] = sub i16 0, [[TMP65]]
; CHECK-NEXT: br label [[IF_END_8:%.*]]
; CHECK: if.then.8:
; CHECK-NEXT: [[ADD_8:%.*]] = add nuw nsw i32 [[CONV5_8]], [[CONV_8]]
; CHECK-NEXT: [[MUL_8:%.*]] = mul i32 [[ADD_8]], [[CONV11_8]]
; CHECK-NEXT: [[SHR_8:%.*]] = lshr i32 [[MUL_8]], 16
-; CHECK-NEXT: [[CONV12_8:%.*]] = trunc i32 [[SHR_8]] to i16
+; CHECK-NEXT: [[CONV12_8:%.*]] = trunc nuw i32 [[SHR_8]] to i16
; CHECK-NEXT: br label [[IF_END_8]]
; CHECK: if.end.8:
; CHECK-NEXT: [[STOREMERGE_8:%.*]] = phi i16 [ [[CONV28_8]], [[IF_ELSE_8]] ], [ [[CONV12_8]], [[IF_THEN_8]] ]
@@ -334,14 +334,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_9:%.*]] = sub nsw i32 [[CONV5_9]], [[CONV_9]]
; CHECK-NEXT: [[MUL25_9:%.*]] = mul i32 [[ADD21_9]], [[CONV11_9]]
; CHECK-NEXT: [[SHR26_9:%.*]] = lshr i32 [[MUL25_9]], 16
-; CHECK-NEXT: [[TMP69:%.*]] = trunc i32 [[SHR26_9]] to i16
+; CHECK-NEXT: [[TMP69:%.*]] = trunc nuw i32 [[SHR26_9]] to i16
; CHECK-NEXT: [[CONV28_9:%.*]] = sub i16 0, [[TMP69]]
; CHECK-NEXT: br label [[IF_END_9:%.*]]
; CHECK: if.then.9:
; CHECK-NEXT: [[ADD_9:%.*]] = add nuw nsw i32 [[CONV5_9]], [[CONV_9]]
; CHECK-NEXT: [[MUL_9:%.*]] = mul i32 [[ADD_9]], [[CONV11_9]]
; CHECK-NEXT: [[SHR_9:%.*]] = lshr i32 [[MUL_9]], 16
-; CHECK-NEXT: [[CONV12_9:%.*]] = trunc i32 [[SHR_9]] to i16
+; CHECK-NEXT: [[CONV12_9:%.*]] = trunc nuw i32 [[SHR_9]] to i16
; CHECK-NEXT: br label [[IF_END_9]]
; CHECK: if.end.9:
; CHECK-NEXT: [[STOREMERGE_9:%.*]] = phi i16 [ [[CONV28_9]], [[IF_ELSE_9]] ], [ [[CONV12_9]], [[IF_THEN_9]] ]
@@ -362,14 +362,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_10:%.*]] = sub nsw i32 [[CONV5_10]], [[CONV_10]]
; CHECK-NEXT: [[MUL25_10:%.*]] = mul i32 [[ADD21_10]], [[CONV11_10]]
; CHECK-NEXT: [[SHR26_10:%.*]] = lshr i32 [[MUL25_10]], 16
-; CHECK-NEXT: [[TMP73:%.*]] = trunc i32 [[SHR26_10]] to i16
+; CHECK-NEXT: [[TMP73:%.*]] = trunc nuw i32 [[SHR26_10]] to i16
; CHECK-NEXT: [[CONV28_10:%.*]] = sub i16 0, [[TMP73]]
; CHECK-NEXT: br label [[IF_END_10:%.*]]
; CHECK: if.then.10:
; CHECK-NEXT: [[ADD_10:%.*]] = add nuw nsw i32 [[CONV5_10]], [[CONV_10]]
; CHECK-NEXT: [[MUL_10:%.*]] = mul i32 [[ADD_10]], [[CONV11_10]]
; CHECK-NEXT: [[SHR_10:%.*]] = lshr i32 [[MUL_10]], 16
-; CHECK-NEXT: [[CONV12_10:%.*]] = trunc i32 [[SHR_10]] to i16
+; CHECK-NEXT: [[CONV12_10:%.*]] = trunc nuw i32 [[SHR_10]] to i16
; CHECK-NEXT: br label [[IF_END_10]]
; CHECK: if.end.10:
; CHECK-NEXT: [[STOREMERGE_10:%.*]] = phi i16 [ [[CONV28_10]], [[IF_ELSE_10]] ], [ [[CONV12_10]], [[IF_THEN_10]] ]
@@ -390,14 +390,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_11:%.*]] = sub nsw i32 [[CONV5_11]], [[CONV_11]]
; CHECK-NEXT: [[MUL25_11:%.*]] = mul i32 [[ADD21_11]], [[CONV11_11]]
; CHECK-NEXT: [[SHR26_11:%.*]] = lshr i32 [[MUL25_11]], 16
-; CHECK-NEXT: [[TMP77:%.*]] = trunc i32 [[SHR26_11]] to i16
+; CHECK-NEXT: [[TMP77:%.*]] = trunc nuw i32 [[SHR26_11]] to i16
; CHECK-NEXT: [[CONV28_11:%.*]] = sub i16 0, [[TMP77]]
; CHECK-NEXT: br label [[IF_END_11:%.*]]
; CHECK: if.then.11:
; CHECK-NEXT: [[ADD_11:%.*]] = add nuw nsw i32 [[CONV5_11]], [[CONV_11]]
; CHECK-NEXT: [[MUL_11:%.*]] = mul i32 [[ADD_11]], [[CONV11_11]]
; CHECK-NEXT: [[SHR_11:%.*]] = lshr i32 [[MUL_11]], 16
-; CHECK-NEXT: [[CONV12_11:%.*]] = trunc i32 [[SHR_11]] to i16
+; CHECK-NEXT: [[CONV12_11:%.*]] = trunc nuw i32 [[SHR_11]] to i16
; CHECK-NEXT: br label [[IF_END_11]]
; CHECK: if.end.11:
; CHECK-NEXT: [[STOREMERGE_11:%.*]] = phi i16 [ [[CONV28_11]], [[IF_ELSE_11]] ], [ [[CONV12_11]], [[IF_THEN_11]] ]
@@ -418,14 +418,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_12:%.*]] = sub nsw i32 [[CONV5_12]], [[CONV_12]]
; CHECK-NEXT: [[MUL25_12:%.*]] = mul i32 [[ADD21_12]], [[CONV11_12]]
; CHECK-NEXT: [[SHR26_12:%.*]] = lshr i32 [[MUL25_12]], 16
-; CHECK-NEXT: [[TMP81:%.*]] = trunc i32 [[SHR26_12]] to i16
+; CHECK-NEXT: [[TMP81:%.*]] = trunc nuw i32 [[SHR26_12]] to i16
; CHECK-NEXT: [[CONV28_12:%.*]] = sub i16 0, [[TMP81]]
; CHECK-NEXT: br label [[IF_END_12:%.*]]
; CHECK: if.then.12:
; CHECK-NEXT: [[ADD_12:%.*]] = add nuw nsw i32 [[CONV5_12]], [[CONV_12]]
; CHECK-NEXT: [[MUL_12:%.*]] = mul i32 [[ADD_12]], [[CONV11_12]]
; CHECK-NEXT: [[SHR_12:%.*]] = lshr i32 [[MUL_12]], 16
-; CHECK-NEXT: [[CONV12_12:%.*]] = trunc i32 [[SHR_12]] to i16
+; CHECK-NEXT: [[CONV12_12:%.*]] = trunc nuw i32 [[SHR_12]] to i16
; CHECK-NEXT: br label [[IF_END_12]]
; CHECK: if.end.12:
; CHECK-NEXT: [[STOREMERGE_12:%.*]] = phi i16 [ [[CONV28_12]], [[IF_ELSE_12]] ], [ [[CONV12_12]], [[IF_THEN_12]] ]
@@ -446,14 +446,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_13:%.*]] = sub nsw i32 [[CONV5_13]], [[CONV_13]]
; CHECK-NEXT: [[MUL25_13:%.*]] = mul i32 [[ADD21_13]], [[CONV11_13]]
; CHECK-NEXT: [[SHR26_13:%.*]] = lshr i32 [[MUL25_13]], 16
-; CHECK-NEXT: [[TMP85:%.*]] = trunc i32 [[SHR26_13]] to i16
+; CHECK-NEXT: [[TMP85:%.*]] = trunc nuw i32 [[SHR26_13]] to i16
; CHECK-NEXT: [[CONV28_13:%.*]] = sub i16 0, [[TMP85]]
; CHECK-NEXT: br label [[IF_END_13:%.*]]
; CHECK: if.then.13:
; CHECK-NEXT: [[ADD_13:%.*]] = add nuw nsw i32 [[CONV5_13]], [[CONV_13]]
; CHECK-NEXT: [[MUL_13:%.*]] = mul i32 [[ADD_13]], [[CONV11_13]]
; CHECK-NEXT: [[SHR_13:%.*]] = lshr i32 [[MUL_13]], 16
-; CHECK-NEXT: [[CONV12_13:%.*]] = trunc i32 [[SHR_13]] to i16
+; CHECK-NEXT: [[CONV12_13:%.*]] = trunc nuw i32 [[SHR_13]] to i16
; CHECK-NEXT: br label [[IF_END_13]]
; CHECK: if.end.13:
; CHECK-NEXT: [[STOREMERGE_13:%.*]] = phi i16 [ [[CONV28_13]], [[IF_ELSE_13]] ], [ [[CONV12_13]], [[IF_THEN_13]] ]
@@ -474,14 +474,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_14:%.*]] = sub nsw i32 [[CONV5_14]], [[CONV_14]]
; CHECK-NEXT: [[MUL25_14:%.*]] = mul i32 [[ADD21_14]], [[CONV11_14]]
; CHECK-NEXT: [[SHR26_14:%.*]] = lshr i32 [[MUL25_14]], 16
-; CHECK-NEXT: [[TMP89:%.*]] = trunc i32 [[SHR26_14]] to i16
+; CHECK-NEXT: [[TMP89:%.*]] = trunc nuw i32 [[SHR26_14]] to i16
; CHECK-NEXT: [[CONV28_14:%.*]] = sub i16 0, [[TMP89]]
; CHECK-NEXT: br label [[IF_END_14:%.*]]
; CHECK: if.then.14:
; CHECK-NEXT: [[ADD_14:%.*]] = add nuw nsw i32 [[CONV5_14]], [[CONV_14]]
; CHECK-NEXT: [[MUL_14:%.*]] = mul i32 [[ADD_14]], [[CONV11_14]]
; CHECK-NEXT: [[SHR_14:%.*]] = lshr i32 [[MUL_14]], 16
-; CHECK-NEXT: [[CONV12_14:%.*]] = trunc i32 [[SHR_14]] to i16
+; CHECK-NEXT: [[CONV12_14:%.*]] = trunc nuw i32 [[SHR_14]] to i16
; CHECK-NEXT: br label [[IF_END_14]]
; CHECK: if.end.14:
; CHECK-NEXT: [[STOREMERGE_14:%.*]] = phi i16 [ [[CONV28_14]], [[IF_ELSE_14]] ], [ [[CONV12_14]], [[IF_THEN_14]] ]
@@ -502,14 +502,14 @@ define i32 @quant_4x4(ptr noundef %dct, ptr noundef %mf, ptr noundef %bias) {
; CHECK-NEXT: [[ADD21_15:%.*]] = sub nsw i32 [[CONV5_15]], [[CONV_15]]
; CHECK-NEXT: [[MUL25_15:%.*]] = mul i32 [[ADD21_15]], [[CONV11_15]]
; CHECK-NEXT: [[SHR26_15:%.*]] = lshr i32 [[MUL25_15]], 16
-; CHECK-NEXT: [[TMP93:%.*]] = trunc i32 [[SHR26_15]] to i16
+; CHECK-NEXT: [[TMP93:%.*]] = trunc nuw i32 [[SHR26_15]] to i16
; CHECK-NEXT: [[CONV28_15:%.*]] = sub i16 0, [[TMP93]]
; CHECK-NEXT: br label [[IF_END_15]]
; CHECK: if.then.15:
; CHECK-NEXT: [[ADD_15:%.*]] = add nuw nsw i32 [[CONV5_15]], [[CONV_15]]
; CHECK-NEXT: [[MUL_15:%.*]] = mul i32 [[ADD_15]], [[CONV11_15]]
; CHECK-NEXT: [[SHR_15:%.*]] = lshr i32 [[MUL_15]], 16
-; CHECK-NEXT: [[CONV12_15:%.*]] = trunc i32 [[SHR_15]] to i16
+; CHECK-NEXT: [[CONV12_15:%.*]] = trunc nuw i32 [[SHR_15]] to i16
; CHECK-NEXT: br label [[IF_END_15]]
; CHECK: if.end.15:
; CHECK-NEXT: [[STOREMERGE_15:%.*]] = phi i16 [ [[CONV28_15]], [[IF_ELSE_15]] ], [ [[CONV12_15]], [[IF_THEN_15]] ]
diff --git a/llvm/test/Transforms/PhaseOrdering/ARM/arm_mult_q15.ll b/llvm/test/Transforms/PhaseOrdering/ARM/arm_mult_q15.ll
index 36bcda4c43ca9b..c6126727598ef2 100644
--- a/llvm/test/Transforms/PhaseOrdering/ARM/arm_mult_q15.ll
+++ b/llvm/test/Transforms/PhaseOrdering/ARM/arm_mult_q15.ll
@@ -69,7 +69,7 @@ define void @arm_mult_q15(ptr %pSrcA, ptr %pSrcB, ptr noalias %pDst, i32 %blockS
; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[CONV2]], [[CONV]]
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[MUL]], 15
; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = tail call i32 @llvm.smin.i32(i32 [[SHR]], i32 32767)
-; CHECK-NEXT: [[CONV3:%.*]] = trunc i32 [[SPEC_SELECT_I]] to i16
+; CHECK-NEXT: [[CONV3:%.*]] = trunc nsw i32 [[SPEC_SELECT_I]] to i16
; CHECK-NEXT: [[INCDEC_PTR4]] = getelementptr inbounds i8, ptr [[PDST_ADDR_04]], i32 2
; CHECK-NEXT: store i16 [[CONV3]], ptr [[PDST_ADDR_04]], align 2
; CHECK-NEXT: [[DEC]] = add i32 [[BLKCNT_06]], -1
diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll
index f17b6c1317263b..25719d2bee521c 100644
--- a/llvm/test/Transforms/SCCP/conditions-ranges.ll
+++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll
@@ -178,7 +178,7 @@ define i32 @f5(i64 %sz) {
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
+; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
entry:
@@ -759,7 +759,7 @@ define i32 @udiv_1(i64 %sz) {
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ [[DIV]], [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
+; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
entry:
@@ -786,7 +786,7 @@ define i32 @udiv_2(i64 %sz) {
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[COND:%.*]] = phi i64 [ 0, [[COND_TRUE]] ], [ 1, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[COND]] to i32
+; CHECK-NEXT: [[CONV:%.*]] = trunc nuw nsw i64 [[COND]] to i32
; CHECK-NEXT: ret i32 [[CONV]]
;
entry:
diff --git a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
index b97b3a0c458168..80d90922c2fbdb 100644
--- a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
+++ b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll
@@ -4,7 +4,7 @@
; x = [100, 301)
define internal i1 @f.trunc(i32 %x) {
; CHECK-LABEL: @f.trunc(
-; CHECK-NEXT: [[T_1:%.*]] = trunc i32 [[X:%.*]] to i16
+; CHECK-NEXT: [[T_1:%.*]] = trunc nuw nsw i32 [[X:%.*]] to i16
; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i16 [[T_1]], 299
; CHECK-NEXT: [[C_4:%.*]] = icmp slt i16 [[T_1]], 101
; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]]
@@ -329,7 +329,7 @@ define i64 @caller.sext_to_zext(i32 %i) {
; CHECK-LABEL: @caller.sext_to_zext(
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[I:%.*]], 9
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]])
+; CHECK-NEXT: [[T:%.*]] = call i64 @f.sext_to_zext(i32 [[CONV]]), !range [[RNG0:![0-9]+]]
; CHECK-NEXT: ret i64 [[T]]
;
%cmp = icmp sle i32 %i, 9
diff --git a/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll b/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
index 0447c82bb55421..fc3e56011d46cd 100644
--- a/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
+++ b/llvm/test/Transforms/SCCP/trunc-nuw-nsw-flags.ll
@@ -6,7 +6,7 @@ define i16 @range_from_and_nuw(i32 %a) {
; CHECK-SAME: i32 [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 65535
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i32 [[AND1]] to i16
; CHECK-NEXT: ret i16 [[TRUNC1]]
;
entry:
@@ -20,7 +20,7 @@ define i8 @range_from_or_nsw(i16 %a) {
; CHECK-SAME: i16 [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND1:%.*]] = or i16 [[A]], -128
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[AND1]] to i8
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i16 [[AND1]] to i8
; CHECK-NEXT: ret i8 [[TRUNC1]]
;
entry:
@@ -34,7 +34,7 @@ define i16 @range_from_and_nuw_nsw(i32 %a) {
; CHECK-SAME: i32 [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], 32767
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[AND1]] to i16
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw nsw i32 [[AND1]] to i16
; CHECK-NEXT: ret i16 [[TRUNC1]]
;
entry:
@@ -67,8 +67,8 @@ define i4 @range_from_sge_sle(i8 %a) {
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[AND1:%.*]] = and i8 [[A]], 7
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i8 [[A]] to i4
-; CHECK-NEXT: [[TRUNC2:%.*]] = trunc i8 [[AND1]] to i4
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i8 [[A]] to i4
+; CHECK-NEXT: [[TRUNC2:%.*]] = trunc nuw nsw i8 [[AND1]] to i4
; CHECK-NEXT: [[XOR1:%.*]] = xor i4 [[TRUNC1]], [[TRUNC2]]
; CHECK-NEXT: ret i4 [[XOR1]]
; CHECK: else:
@@ -99,7 +99,7 @@ define i16 @range_from_sext(i16 %a) {
; CHECK-SAME: i16 [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT1:%.*]] = sext i16 [[A]] to i32
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[SEXT1]] to i16
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i32 [[SEXT1]] to i16
; CHECK-NEXT: ret i16 [[TRUNC1]]
;
entry:
@@ -113,7 +113,7 @@ define i16 @range_from_zext(i16 %a) {
; CHECK-SAME: i16 [[A:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[ZEXT1:%.*]] = zext i16 [[A]] to i32
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i32 [[ZEXT1]] to i16
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i32 [[ZEXT1]] to i16
; CHECK-NEXT: ret i16 [[TRUNC1]]
;
entry:
@@ -127,7 +127,7 @@ define i1 @range_from_select_i1_nuw(i1 %c) {
; CHECK-SAME: i1 [[C:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 1
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nuw i16 [[SELECT1]] to i1
; CHECK-NEXT: ret i1 [[TRUNC1]]
;
entry:
@@ -141,7 +141,7 @@ define i1 @range_from_select_i1_nsw(i1 %c) {
; CHECK-SAME: i1 [[C:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[C]], i16 0, i16 -1
-; CHECK-NEXT: [[TRUNC1:%.*]] = trunc i16 [[SELECT1]] to i1
+; CHECK-NEXT: [[TRUNC1:%.*]] = trunc nsw i16 [[SELECT1]] to i1
; CHECK-NEXT: ret i1 [[TRUNC1]]
;
entry:
diff --git a/llvm/test/Transforms/SCCP/widening.ll b/llvm/test/Transforms/SCCP/widening.ll
index 2223ca44bccdbb..473594eb988da3 100644
--- a/llvm/test/Transforms/SCCP/widening.ll
+++ b/llvm/test/Transforms/SCCP/widening.ll
@@ -438,9 +438,9 @@ define void @foo(ptr %arg) {
; SCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
; SCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
; SCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
-; SCCP-NEXT: i32 1, label [[BB3:%.*]]
-; SCCP-NEXT: i32 2, label [[BB4:%.*]]
-; SCCP-NEXT: i32 4, label [[BB19:%.*]]
+; SCCP-NEXT: i32 1, label [[BB3:%.*]]
+; SCCP-NEXT: i32 2, label [[BB4:%.*]]
+; SCCP-NEXT: i32 4, label [[BB19:%.*]]
; SCCP-NEXT: ]
; SCCP: bb3:
; SCCP-NEXT: unreachable
@@ -449,7 +449,7 @@ define void @foo(ptr %arg) {
; SCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
; SCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
; SCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
-; SCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
+; SCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
; SCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
; SCCP-NEXT: br label [[BB11:%.*]]
; SCCP: bb11:
@@ -475,9 +475,9 @@ define void @foo(ptr %arg) {
; IPSCCP-NEXT: [[TMP:%.*]] = zext i8 undef to i32
; IPSCCP-NEXT: [[TMP2:%.*]] = load i64, ptr [[ARG:%.*]], align 8
; IPSCCP-NEXT: switch i32 [[TMP]], label [[BB20:%.*]] [
-; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
-; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
-; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
+; IPSCCP-NEXT: i32 1, label [[BB3:%.*]]
+; IPSCCP-NEXT: i32 2, label [[BB4:%.*]]
+; IPSCCP-NEXT: i32 4, label [[BB19:%.*]]
; IPSCCP-NEXT: ]
; IPSCCP: bb3:
; IPSCCP-NEXT: unreachable
@@ -486,7 +486,7 @@ define void @foo(ptr %arg) {
; IPSCCP-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 3
; IPSCCP-NEXT: [[TMP7:%.*]] = sub nuw nsw i64 3, [[TMP6]]
; IPSCCP-NEXT: [[TMP8:%.*]] = shl nuw nsw i64 [[TMP7]], 1
-; IPSCCP-NEXT: [[TMP9:%.*]] = trunc i64 [[TMP8]] to i32
+; IPSCCP-NEXT: [[TMP9:%.*]] = trunc nuw nsw i64 [[TMP8]] to i32
; IPSCCP-NEXT: [[TMP10:%.*]] = zext nneg i32 [[TMP9]] to i64
; IPSCCP-NEXT: br label [[BB11:%.*]]
; IPSCCP: bb11:
@@ -615,7 +615,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; SCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
; SCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
; SCCP: bb23:
-; SCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
+; SCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
; SCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
; SCCP-NEXT: br label [[BB31]]
; SCCP: bb25:
@@ -639,7 +639,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; SCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
; SCCP: bb39:
; SCCP-NEXT: [[TMP40:%.*]] = add nsw i32 [[TMP11]], -1
-; SCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
+; SCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
; SCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
; SCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], [[TMP40]]
; SCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
@@ -697,7 +697,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; IPSCCP-NEXT: [[TMP22:%.*]] = icmp eq i32 [[TMP21]], 0
; IPSCCP-NEXT: br i1 [[TMP22]], label [[BB23:%.*]], label [[BB25:%.*]]
; IPSCCP: bb23:
-; IPSCCP-NEXT: [[TMP24:%.*]] = trunc i32 [[TMP3]] to i16
+; IPSCCP-NEXT: [[TMP24:%.*]] = trunc nuw i32 [[TMP3]] to i16
; IPSCCP-NEXT: store i16 [[TMP24]], ptr [[TMP17]], align 2
; IPSCCP-NEXT: br label [[BB31]]
; IPSCCP: bb25:
@@ -720,7 +720,7 @@ define ptr @wobble(ptr %arg, i32 %arg1) align 2 {
; IPSCCP-NEXT: [[C_2:%.*]] = icmp eq i32 [[TMP11]], 8
; IPSCCP-NEXT: br i1 [[C_2]], label [[BB39:%.*]], label [[BB58:%.*]]
; IPSCCP: bb39:
-; IPSCCP-NEXT: [[TMP41:%.*]] = trunc i32 [[TMP3]] to i16
+; IPSCCP-NEXT: [[TMP41:%.*]] = trunc nuw i32 [[TMP3]] to i16
; IPSCCP-NEXT: store i16 [[TMP41]], ptr @global.11, align 1
; IPSCCP-NEXT: [[TMP43:%.*]] = add i32 [[TMP7]], 7
; IPSCCP-NEXT: [[TMP44:%.*]] = mul i32 [[TMP43]], 4
>From 6567424180489a0fc1c423b90c8c40cfa5399b2a Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Sun, 7 Apr 2024 23:00:04 +0800
Subject: [PATCH 3/3] [SCCP] Avoid computing range if the instructions are
already refined.
---
llvm/lib/Transforms/Utils/SCCPSolver.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 3cec6623df33ec..ec50375b5d136e 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -120,6 +120,9 @@ static bool refineInstruction(SCCPSolver &Solver,
};
if (isa<OverflowingBinaryOperator>(Inst)) {
+ if (Inst.hasNoSignedWrap() && Inst.hasNoUnsignedWrap())
+ return false;
+
auto RangeA = GetRange(Inst.getOperand(0));
auto RangeB = GetRange(Inst.getOperand(1));
if (!Inst.hasNoUnsignedWrap()) {
@@ -147,6 +150,9 @@ static bool refineInstruction(SCCPSolver &Solver,
Changed = true;
}
} else if (TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
+ if (TI->hasNoSignedWrap() && TI->hasNoUnsignedWrap())
+ return false;
+
auto Range = GetRange(Inst.getOperand(0));
uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
if (!TI->hasNoUnsignedWrap()) {
More information about the llvm-commits
mailing list