[llvm] 60936b3 - [TypePromotion][RISCV][ARM] Ignore the condition operand of selects. (#215685)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 11 19:33:33 PDT 2026
Author: Craig Topper
Date: 2026-08-11T19:33:27-07:00
New Revision: 60936b312b72a48832344dda12977e78774da9e7
URL: https://github.com/llvm/llvm-project/commit/60936b312b72a48832344dda12977e78774da9e7
DIFF: https://github.com/llvm/llvm-project/commit/60936b312b72a48832344dda12977e78774da9e7.diff
LOG: [TypePromotion][RISCV][ARM] Ignore the condition operand of selects. (#215685)
We don't need to promote the condition operand in order to promote a
select. It must always be an i1 type so it doesn't matter where it comes
from.
The change to pr148084.ll is a regression, but I don't think it's
directly related to select. TypePromotion is using a zero extend
promotion which makes constants that are harder to materialize and
prevents the use of `not`. This kind of thing can happen independent of
selects being involved.
Added:
Modified:
llvm/lib/CodeGen/TypePromotion.cpp
llvm/test/CodeGen/RISCV/pr148084.ll
llvm/test/Transforms/TypePromotion/ARM/casts.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index 507ee820975ac..e9f54fd556bbd 100644
--- a/llvm/lib/CodeGen/TypePromotion.cpp
+++ b/llvm/lib/CodeGen/TypePromotion.cpp
@@ -488,6 +488,10 @@ void IRPromoter::PromoteTree() {
if ((Op->getType() == ExtTy) || !isa<IntegerType>(Op->getType()))
continue;
+ // Skip the condition operand of select.
+ if (isa<SelectInst>(I) && i == 0)
+ continue;
+
if (auto *Const = dyn_cast<ConstantInt>(Op)) {
// For subtract, we only need to zext the constant. We only put it in
// SafeWrap because SafeWrap.size() is used elsewhere.
@@ -857,6 +861,9 @@ bool TypePromotionImpl::TryToPromote(Value *V, unsigned PromotedWidth,
if (auto *I = dyn_cast<Instruction>(V)) {
// Visit operands of any instruction visited.
for (auto &U : I->operands()) {
+ // Skip condition of selects.
+ if (isa<SelectInst>(I) && U.getOperandNo() == 0)
+ continue;
if (!AddLegalInst(U))
return false;
}
diff --git a/llvm/test/CodeGen/RISCV/pr148084.ll b/llvm/test/CodeGen/RISCV/pr148084.ll
index f095d19f10427..47ebcbb54a7d7 100644
--- a/llvm/test/CodeGen/RISCV/pr148084.ll
+++ b/llvm/test/CodeGen/RISCV/pr148084.ll
@@ -11,7 +11,7 @@ define fastcc i16 @search_tx_type() #0 {
; CHECK-NEXT: li a0, 0
; CHECK-NEXT: # %bb.1: # %bb
; CHECK-NEXT: lbu a0, 0(zero)
-; CHECK-NEXT: lh a2, 0(zero)
+; CHECK-NEXT: lhu a2, 0(zero)
; CHECK-NEXT: lw a1, 0(zero)
; CHECK-NEXT: seqz a0, a0
; CHECK-NEXT: addi a0, a0, -1
@@ -165,16 +165,23 @@ define fastcc i16 @search_tx_type() #0 {
; CHECK-NEXT: .LBB0_52: # %bb
; CHECK-NEXT: sgtz a1, a1
; CHECK-NEXT: slli a1, a1, 15
-; CHECK-NEXT: bset a2, zero, a2
-; CHECK-NEXT: and a3, a2, a1
-; CHECK-NEXT: seqz a3, a3
+; CHECK-NEXT: bset a3, zero, a2
+; CHECK-NEXT: and a4, a3, a1
+; CHECK-NEXT: lui a3, 16
; CHECK-NEXT: addi a3, a3, -1
-; CHECK-NEXT: and a2, a2, a3
-; CHECK-NEXT: andn a1, a1, a2
-; CHECK-NEXT: andn a0, a0, a1
-; CHECK-NEXT: # %bb.53: # %get_tx_mask.exit
-; CHECK-NEXT: slli a1, a0, 48
-; CHECK-NEXT: seqz a1, a1
+; CHECK-NEXT: bnez a4, .LBB0_54
+; CHECK-NEXT: # %bb.53: # %bb
+; CHECK-NEXT: mv a2, a3
+; CHECK-NEXT: j .LBB0_55
+; CHECK-NEXT: .LBB0_54:
+; CHECK-NEXT: li a4, -2
+; CHECK-NEXT: rol a2, a4, a2
+; CHECK-NEXT: .LBB0_55: # %bb
+; CHECK-NEXT: and a1, a1, a2
+; CHECK-NEXT: xor a1, a1, a3
+; CHECK-NEXT: and a0, a0, a1
+; CHECK-NEXT: # %bb.56: # %get_tx_mask.exit
+; CHECK-NEXT: seqz a1, a0
; CHECK-NEXT: addi a1, a1, -1
; CHECK-NEXT: and a0, a0, a1
; CHECK-NEXT: ret
diff --git a/llvm/test/Transforms/TypePromotion/ARM/casts.ll b/llvm/test/Transforms/TypePromotion/ARM/casts.ll
index cd25347c095cb..7c3a87db41aa1 100644
--- a/llvm/test/Transforms/TypePromotion/ARM/casts.ll
+++ b/llvm/test/Transforms/TypePromotion/ARM/casts.ll
@@ -400,24 +400,23 @@ if.end:
ret i8 %retval
}
-; TODO: We should be able to remove the uxtb here. The transform fails because
-; the icmp ugt uses an i32, which is too large... but this doesn't matter
-; because it won't be writing a large value to a register as a result.
define i8 @search_through_zext_2(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c, i32 %d) {
; CHECK-LABEL: @search_through_zext_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[ADD]] to i16
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[CONV]], [[C:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[A:%.*]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[B:%.*]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[C:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], [[TMP2]]
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[SUB:%.*]] = sub nuw i8 [[B]], [[A]]
-; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[SUB]] to i32
+; CHECK-NEXT: [[CONV2:%.*]] = sub nuw i32 [[TMP1]], [[TMP0]]
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[CONV2]], [[D:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i8 [[A]], i8 [[B]]
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i32 [[TMP0]], i32 [[TMP1]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[RETVAL:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL:%.*]] = trunc i32 [[RETVAL1]] to i8
; CHECK-NEXT: ret i8 [[RETVAL]]
;
entry:
@@ -438,25 +437,24 @@ if.end:
ret i8 %retval
}
-; TODO: We should be able to remove the uxtb here as all the calculations are
-; performed on i8s. The promotion of i8 to i16 and then the later truncation
-; results in the uxtb.
define i8 @search_through_zext_3(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c, i32 %d) {
; CHECK-LABEL: @search_through_zext_3(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[ADD]] to i16
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[CONV]], [[C:%.*]]
+; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[A:%.*]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[B:%.*]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[C:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], [[TMP2]]
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[CONV]] to i8
-; CHECK-NEXT: [[SUB:%.*]] = sub nuw i8 [[B]], [[TRUNC]]
-; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[SUB]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ADD]], 255
+; CHECK-NEXT: [[CONV2:%.*]] = sub nuw i32 [[TMP1]], [[TMP3]]
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[CONV2]], [[D:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i8 [[A]], i8 [[B]]
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i32 [[TMP0]], i32 [[TMP1]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[RETVAL:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL:%.*]] = trunc i32 [[RETVAL1]] to i8
; CHECK-NEXT: ret i8 [[RETVAL]]
;
entry:
@@ -481,19 +479,21 @@ if.end:
define i8 @search_through_zext_4(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c, i32 %d) {
; CHECK-LABEL: @search_through_zext_4(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CONV_0:%.*]] = zext i8 [[A:%.*]] to i16
-; CHECK-NEXT: [[ADD:%.*]] = add nuw i16 [[CONV_0]], [[C:%.*]]
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[ADD]], [[C]]
+; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[C:%.*]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A:%.*]] to i32
+; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[B:%.*]] to i32
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP1]], [[TMP0]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD]], [[TMP0]]
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT: [[SUB:%.*]] = sub nuw i8 [[B:%.*]], [[TRUNC]]
-; CHECK-NEXT: [[CONV2:%.*]] = zext i8 [[SUB]] to i32
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ADD]], 255
+; CHECK-NEXT: [[CONV2:%.*]] = sub nuw i32 [[TMP2]], [[TMP3]]
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[CONV2]], [[D:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i8 [[A]], i8 [[B]]
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i32 [[TMP1]], i32 [[TMP2]]
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
-; CHECK-NEXT: [[RETVAL:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL1:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RES]], [[IF_THEN]] ]
+; CHECK-NEXT: [[RETVAL:%.*]] = trunc i32 [[RETVAL1]] to i8
; CHECK-NEXT: ret i8 [[RETVAL]]
;
entry:
More information about the llvm-commits
mailing list