[TableGen] Validate the shift amount for !srl, !shl, and !sra operators. (#132492)

The C operator has undefined behavior for out of bounds shifts so we
should check this.
This commit is contained in:
Craig Topper 2025-08-21 22:41:36 -07:00 committed by GitHub
parent d6fae7f921
commit dee25a8a8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 3 deletions

View File

@ -1564,9 +1564,24 @@ const Init *BinOpInit::Fold(const Record *CurRec) const {
case AND: Result = LHSv & RHSv; break;
case OR: Result = LHSv | RHSv; break;
case XOR: Result = LHSv ^ RHSv; break;
case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
case SRA: Result = LHSv >> RHSv; break;
case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
case SHL:
if (RHSv < 0 || RHSv >= 64)
PrintFatalError(CurRec->getLoc(),
"Illegal operation: out of bounds shift");
Result = (uint64_t)LHSv << (uint64_t)RHSv;
break;
case SRA:
if (RHSv < 0 || RHSv >= 64)
PrintFatalError(CurRec->getLoc(),
"Illegal operation: out of bounds shift");
Result = LHSv >> (uint64_t)RHSv;
break;
case SRL:
if (RHSv < 0 || RHSv >= 64)
PrintFatalError(CurRec->getLoc(),
"Illegal operation: out of bounds shift");
Result = (uint64_t)LHSv >> (uint64_t)RHSv;
break;
}
return IntInit::get(getRecordKeeper(), Result);
}

View File

@ -3,6 +3,9 @@
// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
// RUN: not llvm-tblgen -DERROR4 %s 2>&1 | FileCheck --check-prefix=ERROR4 %s
// RUN: not llvm-tblgen -DERROR5 %s 2>&1 | FileCheck --check-prefix=ERROR5 %s
// RUN: not llvm-tblgen -DERROR6 %s 2>&1 | FileCheck --check-prefix=ERROR6 %s
// RUN: not llvm-tblgen -DERROR7 %s 2>&1 | FileCheck --check-prefix=ERROR7 %s
// XFAIL: vg_leak
// CHECK: def shifts
@ -143,3 +146,18 @@ def v954 : Int<!logtwo(-1)>;
// CHECK: def vneg
// CHECK: Value = -2
def vneg : Int<!sub(v925.Value, 927)>;
#ifdef ERROR5
// ERROR5: error: Illegal operation: out of bounds shift
def vshl_neg : Int<!shl(1, -1)>;
#endif
#ifdef ERROR6
// ERROR6: error: Illegal operation: out of bounds shift
def vsra_large : Int<!sra(1, 64)>;
#endif
#ifdef ERROR7
// ERROR7: error: Illegal operation: out of bounds shift
def vsrl_large : Int<!srl(1, 100)>;
#endif