]> granicus.if.org Git - llvm/commitdiff
[ARM] t2_so_imm_neg had a subtle bug in the conversion, and could trigger UB by negat...
authorArtyom Skrobov <Artyom.Skrobov@arm.com>
Wed, 22 Mar 2017 15:09:30 +0000 (15:09 +0000)
committerArtyom Skrobov <Artyom.Skrobov@arm.com>
Wed, 22 Mar 2017 15:09:30 +0000 (15:09 +0000)
Summary: Thanks to Vitaly Buka for helping catch this.

Reviewers: rengolin, jmolloy, efriedma, vitalybuka

Subscribers: llvm-commits, aemerson

Differential Revision: https://reviews.llvm.org/D31242

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298512 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrThumb2.td
test/CodeGen/Thumb/ispositive.ll

index 557099590c3fea02989023c5d702c99e2436519c..45ab65580d46dc635dd903083eb1e70535849e4b 100644 (file)
@@ -111,7 +111,9 @@ def t2_so_imm_notSext : Operand<i32>, PatLeaf<(imm), [{
 // t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
 def t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; }
 def t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{
-  int64_t Value = -(int)N->getZExtValue();
+  int64_t Value = N->getZExtValue();
+  if (Value == 1LL<<31) return false; // INT_MIN cannot be negated
+  Value = -(int)Value;
   return Value && ARM_AM::getT2SOImmVal(Value) != -1;
 }], t2_so_imm_neg_XFORM> {
   let ParserMatchClass = t2_so_imm_neg_asmoperand;
index 8d396878932bbf6b9318f0e2a38798fc428539e6..a9b2c139797eb94f30566b378c85eeba66a238ed 100644 (file)
@@ -9,3 +9,12 @@ entry:
         ret i32 %1
 }
 
+define i32 @test2(i32 %X) {
+entry:
+; CHECK-LABEL: test2:
+; CHECK: lsls r1, r1, #31
+; CHECK-NEXT: adds
+        %tmp1 = sub i32 %X, 2147483648
+        ret i32 %tmp1
+}
+