summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSudharsan Veeravalli <quic_svs@quicinc.com>2024-03-29 09:52:05 +0530
committerGitHub <noreply@github.com>2024-03-28 21:22:05 -0700
commite005a09df5b5c7d210ac7cd8cbddb3a4a8663173 (patch)
tree3547f9bb46bc8bcb8feefb97cf4a9118a3617476
parentc64a328cb4a32e81f8b694162750ec1b8823994c (diff)
[RISCV][TypePromotion] Dont generate truncs if PromotedType is greater than Source Type (#86941)
We currently check if the source and promoted types are not equal before generating truncate instructions. This does not work for RV64 where the promoted type is i64 and this lead to a crash due to the generation of truncate instructions from i32 to i64. Fixes #86400
-rw-r--r--llvm/lib/CodeGen/TypePromotion.cpp2
-rw-r--r--llvm/test/CodeGen/RISCV/rv64-typepromotion.ll27
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index b0830308908d..89aea3a29161 100644
--- a/llvm/lib/CodeGen/TypePromotion.cpp
+++ b/llvm/lib/CodeGen/TypePromotion.cpp
@@ -643,7 +643,7 @@ void IRPromoter::ConvertTruncs() {
ConstantInt *Mask =
ConstantInt::get(SrcTy, APInt::getMaxValue(NumBits).getZExtValue());
Value *Masked = Builder.CreateAnd(Trunc->getOperand(0), Mask);
- if (SrcTy != ExtTy)
+ if (SrcTy->getBitWidth() > ExtTy->getBitWidth())
Masked = Builder.CreateTrunc(Masked, ExtTy);
if (auto *I = dyn_cast<Instruction>(Masked))
diff --git a/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll b/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll
new file mode 100644
index 000000000000..23eae33739c9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv64-typepromotion.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -mtriple=riscv64 -passes=typepromotion -S %s | FileCheck %s
+
+; Test that this does not crash
+define i16 @test(i8 %a, i32 %b) {
+; CHECK-LABEL: define i16 @test(
+; CHECK-SAME: i8 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[A]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[B]] to i16
+; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i64
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i64 [[TMP2]], 0
+; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP0]], 255
+; CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], [[TMP2]]
+; CHECK-NEXT: [[TMP7:%.*]] = trunc i64 [[TMP6]] to i16
+; CHECK-NEXT: ret i16 [[TMP7]]
+;
+entry:
+ %0 = zext i8 %a to i32
+ %1 = trunc i32 %b to i16
+ %2 = icmp eq i16 %1, 0
+ %3 = trunc i32 %0 to i8
+ %4 = zext i8 %3 to i16
+ %5 = xor i16 %4, %1
+ ret i16 %5
+}