Skip to content

Commit 60c7757

Browse files
[ARM] Add missing earlyclobber to sqrshr and uqrshl instructions. (#77782)
This avoids possible undefined behavior using the same register for Rm and Rda. Additionally adds a check in MC to produce an error upon parsing this case.
1 parent 1074b94 commit 60c7757

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

llvm/lib/Target/ARM/ARMInstrMVE.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def MVE_URSHR : MVE_ScalarShiftSRegImm<"urshr", 0b01>;
478478

479479
class MVE_ScalarShiftSRegReg<string iname, bits<2> op5_4>
480480
: MVE_ScalarShiftSingleReg<iname, (ins rGPR:$RdaSrc, rGPR:$Rm),
481-
"$RdaSrc, $Rm", "$RdaDest = $RdaSrc",
481+
"$RdaSrc, $Rm", "@earlyclobber $RdaDest,$RdaDest = $RdaSrc",
482482
[(set rGPR:$RdaDest,
483483
(i32 (!cast<Intrinsic>("int_arm_mve_" # iname)
484484
(i32 rGPR:$RdaSrc), (i32 rGPR:$Rm))))]> {

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8308,6 +8308,14 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst,
83088308
return Error (Operands[3]->getStartLoc(), "Q-register indexes must be 2 and 0 or 3 and 1");
83098309
break;
83108310
}
8311+
case ARM::MVE_SQRSHR:
8312+
case ARM::MVE_UQRSHL: {
8313+
if (Operands[2]->getReg() == Operands[3]->getReg()) {
8314+
return Error(Operands[2]->getStartLoc(),
8315+
"Rda register and Rm register can't be identical");
8316+
}
8317+
break;
8318+
}
83118319
case ARM::UMAAL:
83128320
case ARM::UMLAL:
83138321
case ARM::UMULL:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; RUN: llc -mtriple armv8.1m.main -mattr=+mve %s -o - | FileCheck %s
2+
3+
; Check that we don't create an unpredictable sqrshr or uqrshl instruction,
4+
; e.g. sqrshr r0, r0
5+
6+
declare i32 @llvm.arm.mve.sqrshr(i32, i32) #1
7+
declare i32 @llvm.arm.mve.uqrshl(i32, i32) #1
8+
9+
define i32 @sqrshr() #0 {
10+
; CHECK-LABEL: sqrshr
11+
; CHECK-NOT: sqrshr r[[REG:[0-9]+]], r[[REG]]
12+
%1 = tail call i32 @llvm.arm.mve.sqrshr(i32 1, i32 1)
13+
ret i32 %1
14+
}
15+
16+
define i32 @uqrshl() #0 {
17+
; CHECK-LABEL: uqrshl
18+
; CHECK-NOT: uqrshl r[[REG:[0-9]+]], r[[REG]]
19+
%1 = tail call i32 @llvm.arm.mve.uqrshl(i32 1, i32 1)
20+
ret i32 %1
21+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@ RUN: not llvm-mc -triple armv8.1m.main -mattr=+mve < %s 2>&1 | FileCheck %s
2+
3+
sqrshr r1, r1
4+
@ CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Rda register and Rm register can't be identical
5+
uqrshl r1, r1
6+
@ CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Rda register and Rm register can't be identical

0 commit comments

Comments
 (0)