[llvm] [RISCV][TypePromotion] Dont generate truncs if PromotedType is greater than Source Type (PR #86941)

Sudharsan Veeravalli via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 28 05:21:00 PDT 2024


https://github.com/svs-quic created https://github.com/llvm/llvm-project/pull/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 

>From 6746f8e72d02d79c84978b85d761187888944a30 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Thu, 28 Mar 2024 17:40:03 +0530
Subject: [PATCH] [RISCV][TypePromotion] Fix crash with rv64

---
 llvm/lib/CodeGen/TypePromotion.cpp            |  2 +-
 llvm/test/CodeGen/RISCV/rv64-typepromotion.ll | 27 +++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/RISCV/rv64-typepromotion.ll

diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index b0830308908d6e..89aea3a2916118 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 00000000000000..bee42274741ef0
--- /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:    [[CONV31_I1161_I:%.*]] = trunc i32 [[B]] to i16
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i16 [[CONV31_I1161_I]] to i64
+; CHECK-NEXT:    [[CMP_I_I_I1163_I:%.*]] = icmp eq i64 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP5:%.*]] = and i32 [[TMP0]], 255
+; CHECK-NEXT:    [[TMP3:%.*]] = zext i32 [[TMP5]] to i64
+; CHECK-NEXT:    [[TMP4:%.*]] = xor i64 [[TMP3]], [[TMP1]]
+; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP4]] to i16
+; CHECK-NEXT:    ret i16 [[TMP2]]
+;
+entry:
+  %0 = zext i8 %a to i32
+  %conv31.i1161.i = trunc i32 %b to i16
+  %cmp.i.i.i1163.i = icmp eq i16 %conv31.i1161.i, 0
+  %rem.i.i69.rhs.trunc.i1165.i = trunc i32 %0 to i8
+  %1 = zext i8 %rem.i.i69.rhs.trunc.i1165.i to i16
+  %2 = xor i16 %1, %conv31.i1161.i
+  ret i16 %2
+}



More information about the llvm-commits mailing list