DAGCombiner: Don't drop extension behavior when shrinking a load when unsafe.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 6 Jul 2013 14:05:09 +0000 (14:05 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 6 Jul 2013 14:05:09 +0000 (14:05 +0000)
ReduceLoadWidth unconditionally drops extensions from loads. Limit it to the
case when all of the bits the extension would otherwise produce are dropped by
the shrink. It would be possible to shrink the load in more cases by merging
the extensions, but this isn't trivial and a very rare case. I left a TODO for
that case.

Fixes PR16551.

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

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
test/CodeGen/X86/shrink-compare.ll

index 1688fc495ad9d71ba86a058f77ef6aa074095487..276a5b929b0795e784dcabb88ba626248e9163bf 100644 (file)
@@ -5220,6 +5220,13 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
   if (LN0->getNumValues() > 2)
     return SDValue();
 
+  // If the load that we're shrinking is an extload and we're not just
+  // discarding the extension we can't simply shrink the load. Bail.
+  // TODO: It would be possible to merge the extensions in some cases.
+  if (LN0->getExtensionType() != ISD::NON_EXTLOAD &&
+      LN0->getMemoryVT().getSizeInBits() < ExtVT.getSizeInBits() + ShAmt)
+    return SDValue();
+
   EVT PtrType = N0.getOperand(1).getValueType();
 
   if (PtrType == MVT::Untyped || PtrType.isExtended())
index 83793f000d5952e20f2bf2f8a6d191f54e7b935b..30a5b6207db63f0473cf5237c1c70582c28f2d99 100644 (file)
@@ -66,3 +66,26 @@ lor.end:                                          ; preds = %lor.rhs, %entry
   %p = phi i1 [ true, %entry ], [ %tobool1, %lor.rhs ]
   ret i1 %p
 }
+
+@x = global { i8, i8, i8, i8, i8, i8, i8, i8 } { i8 1, i8 0, i8 0, i8 0, i8 1, i8 0, i8 0, i8 1 }, align 4
+
+; PR16551
+define void @test5(i32 %X) nounwind {
+entry:
+  %bf.load = load i56* bitcast ({ i8, i8, i8, i8, i8, i8, i8, i8 }* @x to i56*), align 4
+  %bf.lshr = lshr i56 %bf.load, 32
+  %bf.cast = trunc i56 %bf.lshr to i32
+  %cmp = icmp ne i32 %bf.cast, 1
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  tail call void @bar() nounwind
+  br label %if.end
+
+if.end:
+  ret void
+
+; CHECK: test5:
+; CHECK-NOT: cmpl $1,{{.*}}x+4
+; CHECK: ret
+}