]> granicus.if.org Git - llvm/commitdiff
[SystemZ] Validate shifted compare value in adjustForTestUnderMask
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 5 Dec 2017 19:42:07 +0000 (19:42 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Tue, 5 Dec 2017 19:42:07 +0000 (19:42 +0000)
When folding a shift into a test-under-mask comparison, make sure that
there is no loss of precision when creating the shifted comparison
value.  This usually never happens, except for certain always-true
comparisons in unoptimized code.

Fixes PR35529.

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

lib/Target/SystemZ/SystemZISelLowering.cpp
test/CodeGen/SystemZ/int-cmp-47.ll

index ad14e5e34e2ec3ede7bb1b8c7025f5f83f4ea688..c239cd5ad4688b8bc339e8a55198cb774d814748 100644 (file)
@@ -2201,6 +2201,7 @@ static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL,
       NewC.Op0.getOpcode() == ISD::SHL &&
       isSimpleShift(NewC.Op0, ShiftVal) &&
       (MaskVal >> ShiftVal != 0) &&
+      ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
       (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
                                         MaskVal >> ShiftVal,
                                         CmpVal >> ShiftVal,
@@ -2211,6 +2212,7 @@ static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL,
              NewC.Op0.getOpcode() == ISD::SRL &&
              isSimpleShift(NewC.Op0, ShiftVal) &&
              (MaskVal << ShiftVal != 0) &&
+             ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
              (NewCCMask = getTestUnderMaskCond(BitSize, NewC.CCMask,
                                                MaskVal << ShiftVal,
                                                CmpVal << ShiftVal,
index dc87284ff5f5fdb28d36d9c8f1973b4144519d12..3a07ed339bb3514de9c1519a10d5f4d631e9ee27 100644 (file)
@@ -342,3 +342,25 @@ store:
 exit:
   ret void
 }
+
+; Check that we don't fold a shift if the comparison value
+; would need to be shifted out of range
+define void @f19(i64 %a) {
+; CHECK-LABEL: f19:
+; CHECK-NOT: tmhh
+; CHECK: srlg [[REG:%r[0-5]]], %r2, 63
+; CHECK: cgibl [[REG]], 3, 0(%r14)
+; CHECK: br %r14
+entry:
+  %shr = lshr i64 %a, 63
+  %cmp = icmp ult i64 %shr, 3
+  br i1 %cmp, label %exit, label %store
+
+store:
+  store i32 1, i32 *@g
+  br label %exit
+
+exit:
+  ret void
+}
+