Skip to content

Commit fe05a0a

Browse files
committed
[SDAG] avoid udiv/urem transform for vector/scalar type mismatches
This solves the crashing from issue llvm#58994. I don't know anything about VE, so I don't know if the output is as expected or even correct.
1 parent e487356 commit fe05a0a

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4477,10 +4477,11 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
44774477

44784478
// fold (udiv X, -1) -> select(X == -1, 1, 0)
44794479
ConstantSDNode *N1C = isConstOrConstSplat(N1);
4480-
if (N1C && N1C->isAllOnes())
4480+
if (N1C && N1C->isAllOnes() && CCVT.isVector() == VT.isVector()) {
44814481
return DAG.getSelect(DL, VT, DAG.getSetCC(DL, CCVT, N0, N1, ISD::SETEQ),
44824482
DAG.getConstant(1, DL, VT),
44834483
DAG.getConstant(0, DL, VT));
4484+
}
44844485

44854486
if (SDValue V = simplifyDivRem(N, DAG))
44864487
return V;
@@ -4583,7 +4584,8 @@ SDValue DAGCombiner::visitREM(SDNode *N) {
45834584

45844585
// fold (urem X, -1) -> select(FX == -1, 0, FX)
45854586
// Freeze the numerator to avoid a miscompile with an undefined value.
4586-
if (!isSigned && llvm::isAllOnesOrAllOnesSplat(N1, /*AllowUndefs*/ false)) {
4587+
if (!isSigned && llvm::isAllOnesOrAllOnesSplat(N1, /*AllowUndefs*/ false) &&
4588+
CCVT.isVector() == VT.isVector()) {
45874589
SDValue F0 = DAG.getFreeze(N0);
45884590
SDValue EqualsNeg1 = DAG.getSetCC(DL, CCVT, F0, N1, ISD::SETEQ);
45894591
return DAG.getSelect(DL, VT, EqualsNeg1, DAG.getConstant(0, DL, VT), F0);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=ve -mattr=+vpu | FileCheck %s
3+
4+
; This would assert because VE specified that all setcc
5+
; nodes (even with vector operands) return a scalar value.
6+
7+
define <4 x i8> @udiv_by_minus_one(<4 x i8> %x) {
8+
; CHECK-LABEL: udiv_by_minus_one:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: and %s0, %s0, (56)0
11+
; CHECK-NEXT: and %s1, %s1, (56)0
12+
; CHECK-NEXT: and %s2, %s2, (56)0
13+
; CHECK-NEXT: and %s3, %s3, (56)0
14+
; CHECK-NEXT: divu.w %s3, %s3, (56)0
15+
; CHECK-NEXT: divu.w %s2, %s2, (56)0
16+
; CHECK-NEXT: divu.w %s1, %s1, (56)0
17+
; CHECK-NEXT: divu.w %s0, %s0, (56)0
18+
; CHECK-NEXT: b.l.t (, %s10)
19+
%r = udiv <4 x i8> %x, <i8 255, i8 255, i8 255, i8 255>
20+
ret <4 x i8> %r
21+
}
22+
23+
define <4 x i8> @urem_by_minus_one(<4 x i8> %x) {
24+
; CHECK-LABEL: urem_by_minus_one:
25+
; CHECK: # %bb.0:
26+
; CHECK-NEXT: and %s0, %s0, (56)0
27+
; CHECK-NEXT: and %s1, %s1, (56)0
28+
; CHECK-NEXT: and %s2, %s2, (56)0
29+
; CHECK-NEXT: and %s3, %s3, (56)0
30+
; CHECK-NEXT: divu.w %s4, %s3, (56)0
31+
; CHECK-NEXT: muls.w.sx %s4, %s4, (56)0
32+
; CHECK-NEXT: subs.w.sx %s3, %s3, %s4
33+
; CHECK-NEXT: divu.w %s4, %s2, (56)0
34+
; CHECK-NEXT: muls.w.sx %s4, %s4, (56)0
35+
; CHECK-NEXT: subs.w.sx %s2, %s2, %s4
36+
; CHECK-NEXT: divu.w %s4, %s1, (56)0
37+
; CHECK-NEXT: muls.w.sx %s4, %s4, (56)0
38+
; CHECK-NEXT: subs.w.sx %s1, %s1, %s4
39+
; CHECK-NEXT: divu.w %s4, %s0, (56)0
40+
; CHECK-NEXT: muls.w.sx %s4, %s4, (56)0
41+
; CHECK-NEXT: subs.w.sx %s0, %s0, %s4
42+
; CHECK-NEXT: b.l.t (, %s10)
43+
%r = urem <4 x i8> %x, <i8 255, i8 255, i8 255, i8 255>
44+
ret <4 x i8> %r
45+
}

0 commit comments

Comments
 (0)