Skip to content

Commit 54ef0e0

Browse files
authored
[LoongArch] Fix out-of-range assert in DAG constant getting (llvm#141586)
Fixes llvm#141583
1 parent 4f1291e commit 54ef0e0

File tree

5 files changed

+28
-15
lines changed

5 files changed

+28
-15
lines changed

llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void LoongArchDAGToDAGISel::Select(SDNode *Node) {
7676
Result = CurDAG->getMachineNode(
7777
Inst.Opc, DL, GRLenVT,
7878
{SrcReg, SrcReg,
79-
CurDAG->getTargetConstant(Inst.Imm >> 32, DL, GRLenVT),
79+
CurDAG->getSignedTargetConstant(Inst.Imm >> 32, DL, GRLenVT),
8080
CurDAG->getTargetConstant(Inst.Imm & 0xFF, DL, GRLenVT)});
8181
break;
8282
default:
@@ -233,7 +233,7 @@ bool LoongArchDAGToDAGISel::SelectAddrConstant(SDValue Addr, SDValue &Base,
233233
if (!isInt<12>(CVal))
234234
return false;
235235
Base = CurDAG->getRegister(LoongArch::R0, VT);
236-
Offset = CurDAG->getTargetConstant(SignExtend64<12>(CVal), DL, VT);
236+
Offset = CurDAG->getSignedTargetConstant(SignExtend64<12>(CVal), DL, VT);
237237
return true;
238238
}
239239

@@ -255,7 +255,7 @@ bool LoongArchDAGToDAGISel::SelectAddrRegImm12(SDValue Addr, SDValue &Base,
255255
int64_t Imm = cast<ConstantSDNode>(Addr.getOperand(1))->getSExtValue();
256256
if (isInt<12>(Imm)) {
257257
Base = Addr.getOperand(0);
258-
Offset = CurDAG->getTargetConstant(SignExtend64<12>(Imm), DL, VT);
258+
Offset = CurDAG->getSignedTargetConstant(SignExtend64<12>(Imm), DL, VT);
259259
return true;
260260
}
261261
}
@@ -398,8 +398,8 @@ bool LoongArchDAGToDAGISel::selectVSplatImm(SDValue N, SDValue &SplatVal) {
398398
if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
399399
ImmValue.getBitWidth() == EltTy.getSizeInBits()) {
400400
if (IsSigned && ImmValue.isSignedIntN(ImmBitSize)) {
401-
SplatVal = CurDAG->getTargetConstant(ImmValue.getSExtValue(), SDLoc(N),
402-
Subtarget->getGRLenVT());
401+
SplatVal = CurDAG->getSignedTargetConstant(
402+
ImmValue.getSExtValue(), SDLoc(N), Subtarget->getGRLenVT());
403403
return true;
404404
}
405405
if (!IsSigned && ImmValue.isIntN(ImmBitSize)) {
@@ -425,7 +425,7 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,
425425
int32_t Log2 = (~ImmValue).exactLogBase2();
426426

427427
if (Log2 != -1) {
428-
SplatImm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);
428+
SplatImm = CurDAG->getSignedTargetConstant(Log2, SDLoc(N), EltTy);
429429
return true;
430430
}
431431
}
@@ -446,7 +446,7 @@ bool LoongArchDAGToDAGISel::selectVSplatUimmPow2(SDValue N,
446446
int32_t Log2 = ImmValue.exactLogBase2();
447447

448448
if (Log2 != -1) {
449-
SplatImm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);
449+
SplatImm = CurDAG->getSignedTargetConstant(Log2, SDLoc(N), EltTy);
450450
return true;
451451
}
452452
}

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4410,7 +4410,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
44104410
LLVM_DEBUG(dbgs() << "Perform OR combine: match pattern 5\n");
44114411
return DAG.getNode(
44124412
LoongArchISD::BSTRINS, DL, ValTy, N0.getOperand(0),
4413-
DAG.getConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy),
4413+
DAG.getSignedConstant(CN1->getSExtValue() >> MaskIdx0, DL, ValTy),
44144414
DAG.getConstant(ValBits == 32 ? (MaskIdx0 + (MaskLen0 & 31) - 1)
44154415
: (MaskIdx0 + MaskLen0 - 1),
44164416
DL, GRLenVT),

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -524,22 +524,22 @@ def ImmSubFrom32 : SDNodeXForm<imm, [{
524524

525525
// Return the lowest 12 bits of the signed immediate.
526526
def LO12: SDNodeXForm<imm, [{
527-
return CurDAG->getTargetConstant(SignExtend64<12>(N->getSExtValue()),
528-
SDLoc(N), N->getValueType(0));
527+
return CurDAG->getSignedTargetConstant(SignExtend64<12>(N->getSExtValue()),
528+
SDLoc(N), N->getValueType(0));
529529
}]>;
530530

531531
// Return the higher 16 bits of the signed immediate.
532532
def HI16 : SDNodeXForm<imm, [{
533-
return CurDAG->getTargetConstant(N->getSExtValue() >> 16, SDLoc(N),
534-
N->getValueType(0));
533+
return CurDAG->getSignedTargetConstant(N->getSExtValue() >> 16, SDLoc(N),
534+
N->getValueType(0));
535535
}]>;
536536

537537
// Return the higher 16 bits of the signed immediate, adjusted for use within an
538538
// `addu16i.d + addi` pair.
539539
def HI16ForAddu16idAddiPair: SDNodeXForm<imm, [{
540540
auto Imm = N->getSExtValue();
541-
return CurDAG->getTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16,
542-
SDLoc(N), N->getValueType(0));
541+
return CurDAG->getSignedTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16,
542+
SDLoc(N), N->getValueType(0));
543543
}]>;
544544

545545
def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;

llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ def lsxsplatf64 : PatFrag<(ops node:$e0),
221221

222222
def to_valid_timm : SDNodeXForm<timm, [{
223223
auto CN = cast<ConstantSDNode>(N);
224-
return CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(N), Subtarget->getGRLenVT());
224+
return CurDAG->getSignedTargetConstant(CN->getSExtValue(), SDLoc(N),
225+
Subtarget->getGRLenVT());
225226
}]>;
226227

227228
// FP immediate of VLDI patterns.

llvm/test/CodeGen/LoongArch/bstrins_w.ll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,18 @@ define i32 @pat8(i32 %c) nounwind {
207207
ret i32 %or
208208
}
209209

210+
define i32 @pat9(i32 %a) {
211+
; CHECK-LABEL: pat9:
212+
; CHECK: # %bb.0:
213+
; CHECK-NEXT: lu12i.w $a1, -8
214+
; CHECK-NEXT: ori $a1, $a1, 564
215+
; CHECK-NEXT: bstrins.w $a0, $a1, 31, 16
216+
; CHECK-NEXT: ret
217+
%and = and i32 %a, 65535 ; 0x0000ffff
218+
%or = or i32 %and, -2110521344 ; 0x82340000
219+
ret i32 %or
220+
}
221+
210222
;; Test that bstrins.w is not generated because constant OR operand
211223
;; doesn't fit into bits cleared by constant AND operand.
212224
define i32 @no_bstrins_w(i32 %a) nounwind {

0 commit comments

Comments
 (0)