From bf34dd311ff5a352e074fdc7ba42383dac2c630a Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Thu, 17 Jul 2025 16:11:55 +0000 Subject: [PATCH 1/2] [AIX] Handle arbitrary sized integers when lowering formal arguments passed on the stack --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 16 +++++++-- .../PowerPC/aix-lower-arbitrary-sized-ints.ll | 33 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 459525ed4ee9a..c7c42c05adc5b 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7296,9 +7296,19 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX( if (!ArgVT.isVector() && !ValVT.isVector() && ArgVT.isInteger() && ValVT.isInteger() && ArgVT.getScalarSizeInBits() < ValVT.getScalarSizeInBits()) { - SDValue ArgValueTrunc = DAG.getNode( - ISD::TRUNCATE, dl, ArgVT.getSimpleVT() == MVT::i1 ? MVT::i8 : ArgVT, - ArgValue); + // It is possible to have either real integer values that aren't + // the power of two sizes, or integers that were not originally + // integers. In the latter case, these could have came from structs, + // and these integers would not have an extend on the parameter. + // Since these types of integers do not have an extend specified + // in the first place, the type of extend that we do should not matter. + EVT TruncatedArgVT; + if (ArgVT.isSimple()) + TruncatedArgVT = ArgVT.getSimpleVT() == MVT::i1 ? MVT::i8 : ArgVT; + else + TruncatedArgVT = ArgVT; + SDValue ArgValueTrunc = + DAG.getNode(ISD::TRUNCATE, dl, TruncatedArgVT, ArgValue); SDValue ArgValueExt = ArgSignExt ? DAG.getSExtOrTrunc(ArgValueTrunc, dl, ValVT) : DAG.getZExtOrTrunc(ArgValueTrunc, dl, ValVT); diff --git a/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll b/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll new file mode 100644 index 0000000000000..297d2a3e10f94 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll @@ -0,0 +1,33 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc --verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefixes=CHECK,CHECK32 +; RUN: llc --verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefixes=CHECK,CHECK64 + +define ptr @lower_args(ptr %_0, i32 %0, i32 %1, i32 %2, i32 %3, ptr %4, ptr %5, i64 %6, i24 %7) { +; CHECK-LABEL: lower_args: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: blr +entry: + ret ptr %_0 +} + +define i32 @lower_args2(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i24 %i) { +; CHECK32-LABEL: lower_args2: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: lwz 3, 56(1) +; CHECK32-NEXT: addi 3, 3, 255 +; CHECK32-NEXT: clrlwi 3, 3, 8 +; CHECK32-NEXT: blr +; +; CHECK64-LABEL: lower_args2: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: lwz 3, 116(1) +; CHECK64-NEXT: addi 3, 3, 255 +; CHECK64-NEXT: clrldi 3, 3, 40 +; CHECK64-NEXT: blr +entry: + %0 = add i24 %i, 255 + %1 = zext i24 %0 to i32 + ret i32 %1 +} From 057dcb31112331a0d227530c18e451e92c325450 Mon Sep 17 00:00:00 2001 From: Amy Kwan Date: Fri, 25 Jul 2025 04:44:37 +0000 Subject: [PATCH 2/2] Add extra test for signext, simplify variable assignment and update comments. --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 14 +++--- .../PowerPC/aix-lower-arbitrary-sized-ints.ll | 50 +++++++++++++++---- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index c7c42c05adc5b..f179873b4dbd2 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -7296,17 +7296,15 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX( if (!ArgVT.isVector() && !ValVT.isVector() && ArgVT.isInteger() && ValVT.isInteger() && ArgVT.getScalarSizeInBits() < ValVT.getScalarSizeInBits()) { - // It is possible to have either real integer values that aren't - // the power of two sizes, or integers that were not originally - // integers. In the latter case, these could have came from structs, + // It is possible to have either real integer values + // or integers that were not originally integers. + // In the latter case, these could have came from structs, // and these integers would not have an extend on the parameter. // Since these types of integers do not have an extend specified // in the first place, the type of extend that we do should not matter. - EVT TruncatedArgVT; - if (ArgVT.isSimple()) - TruncatedArgVT = ArgVT.getSimpleVT() == MVT::i1 ? MVT::i8 : ArgVT; - else - TruncatedArgVT = ArgVT; + EVT TruncatedArgVT = ArgVT.isSimple() && ArgVT.getSimpleVT() == MVT::i1 + ? MVT::i8 + : ArgVT; SDValue ArgValueTrunc = DAG.getNode(ISD::TRUNCATE, dl, TruncatedArgVT, ArgValue); SDValue ArgValueExt = diff --git a/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll b/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll index 297d2a3e10f94..c119da6e050a9 100644 --- a/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll +++ b/llvm/test/CodeGen/PowerPC/aix-lower-arbitrary-sized-ints.ll @@ -1,8 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc --verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \ -; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefixes=CHECK,CHECK32 +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | \ +; RUN: FileCheck %s --check-prefixes=CHECK,CHECK32 ; RUN: llc --verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ -; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefixes=CHECK,CHECK64 +; RUN: -ppc-asm-full-reg-names -mcpu=pwr8 < %s | \ +; RUN: FileCheck %s --check-prefixes=CHECK,CHECK64 define ptr @lower_args(ptr %_0, i32 %0, i32 %1, i32 %2, i32 %3, ptr %4, ptr %5, i64 %6, i24 %7) { ; CHECK-LABEL: lower_args: @@ -12,22 +14,48 @@ entry: ret ptr %_0 } -define i32 @lower_args2(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i24 %i) { -; CHECK32-LABEL: lower_args2: +define i32 @lower_args_withops_zeroext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i24 %i) { +; CHECK32-LABEL: lower_args_withops_zeroext: ; CHECK32: # %bb.0: # %entry -; CHECK32-NEXT: lwz 3, 56(1) -; CHECK32-NEXT: addi 3, 3, 255 -; CHECK32-NEXT: clrlwi 3, 3, 8 +; CHECK32-NEXT: lwz r3, 56(r1) +; CHECK32-NEXT: addi r3, r3, 255 +; CHECK32-NEXT: clrlwi r3, r3, 8 ; CHECK32-NEXT: blr ; -; CHECK64-LABEL: lower_args2: +; CHECK64-LABEL: lower_args_withops_zeroext: ; CHECK64: # %bb.0: # %entry -; CHECK64-NEXT: lwz 3, 116(1) -; CHECK64-NEXT: addi 3, 3, 255 -; CHECK64-NEXT: clrldi 3, 3, 40 +; CHECK64-NEXT: lwz r3, 116(r1) +; CHECK64-NEXT: addi r3, r3, 255 +; CHECK64-NEXT: clrldi r3, r3, 40 ; CHECK64-NEXT: blr entry: %0 = add i24 %i, 255 %1 = zext i24 %0 to i32 ret i32 %1 } + +define i32 @lower_args_withops_signext(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i24 signext %i) { +; CHECK32-LABEL: lower_args_withops_signext: +; CHECK32: # %bb.0: # %entry +; CHECK32-NEXT: lwz r3, 56(r1) +; CHECK32-NEXT: slwi r3, r3, 8 +; CHECK32-NEXT: srawi r3, r3, 8 +; CHECK32-NEXT: slwi r3, r3, 8 +; CHECK32-NEXT: addi r3, r3, 22272 +; CHECK32-NEXT: srawi r3, r3, 8 +; CHECK32-NEXT: blr +; +; CHECK64-LABEL: lower_args_withops_signext: +; CHECK64: # %bb.0: # %entry +; CHECK64-NEXT: lwz r3, 116(r1) +; CHECK64-NEXT: slwi r3, r3, 8 +; CHECK64-NEXT: srawi r3, r3, 8 +; CHECK64-NEXT: addi r3, r3, 87 +; CHECK64-NEXT: sldi r3, r3, 40 +; CHECK64-NEXT: sradi r3, r3, 40 +; CHECK64-NEXT: blr +entry: + %0 = add i24 %i, 87 + %1 = sext i24 %0 to i32 + ret i32 %1 +}