[PATCH] D69038: [InstCombine] Fix miscompile bug in canEvaluateShuffled

Bjorn Pettersson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 16 07:11:40 PDT 2019


bjope created this revision.
bjope added a reviewer: spatel.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

Add restrictions in canEvaluateShuffled to prevent that we for example
transform

  %0 = insertelement <2 x i16> undef, i16 %a, i32 0
  %1 = srem <2 x i16> %0, <i16 2, i16 1>
  %2 = shufflevector <2 x i16> %1, <2 x i16> undef, <2 x i32> <i32 undef, i32 0>

into

  %1 = insertelement <2 x i16> undef, i16 %a, i32 1
  %2 = srem <2 x i16> %1, <i16 undef, i16 2>

as having an undef denominator makes the srem undefined (for all
vector elements).

Fixes: https://bugs.llvm.org/show_bug.cgi?id=43689


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69038

Files:
  llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
  llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll


Index: llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll
===================================================================
--- llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll
+++ llvm/test/Transforms/InstCombine/shufflevector-div-rem.ll
@@ -8,7 +8,12 @@
 ; extracting the second element in the vector).
 define i16 @test1(i16 %a, i1 %cmp) {
 ; CHECK-LABEL: @test1(
-; CHECK-NEXT:    ret i16 1
+; CHECK-NEXT:    [[SPLATINSERT:%.*]] = insertelement <2 x i16> undef, i16 [[A:%.*]], i32 0
+; CHECK-NEXT:    [[TMP1:%.*]] = srem <2 x i16> [[SPLATINSERT]], <i16 2, i16 1>
+; CHECK-NEXT:    [[SPLAT_OP:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> undef, <2 x i32> <i32 undef, i32 0>
+; CHECK-NEXT:    [[T2:%.*]] = select i1 [[CMP:%.*]], <2 x i16> <i16 undef, i16 1>, <2 x i16> [[SPLAT_OP]]
+; CHECK-NEXT:    [[T3:%.*]] = extractelement <2 x i16> [[T2]], i32 1
+; CHECK-NEXT:    ret i16 [[T3]]
 ;
   %splatinsert = insertelement <2 x i16> undef, i16 %a, i32 0
   %splat = shufflevector <2 x i16> %splatinsert, <2 x i16> undef, <2 x i32> zeroinitializer
@@ -23,7 +28,11 @@
 ; transform the shufflevector by doing "evaluateInDifferentElementOrder".
 define <2 x i16> @test2(i16 %a, i1 %cmp) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    ret <2 x i16> <i16 77, i16 99>
+; CHECK-NEXT:    [[SPLATINSERT:%.*]] = insertelement <2 x i16> undef, i16 [[A:%.*]], i32 0
+; CHECK-NEXT:    [[T1:%.*]] = srem <2 x i16> [[SPLATINSERT]], <i16 2, i16 1>
+; CHECK-NEXT:    [[SPLAT_OP:%.*]] = shufflevector <2 x i16> [[T1]], <2 x i16> undef, <2 x i32> <i32 undef, i32 0>
+; CHECK-NEXT:    [[T2:%.*]] = select i1 [[CMP:%.*]], <2 x i16> <i16 77, i16 99>, <2 x i16> [[SPLAT_OP]]
+; CHECK-NEXT:    ret <2 x i16> [[T2]]
 ;
   %splatinsert = insertelement <2 x i16> undef, i16 %a, i32 0
   %t1 = srem <2 x i16> %splatinsert, <i16 2, i16 1>
Index: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -1061,17 +1061,22 @@
   if (Depth == 0) return false;
 
   switch (I->getOpcode()) {
+    case Instruction::UDiv:
+    case Instruction::SDiv:
+    case Instruction::FDiv:
+    case Instruction::URem:
+    case Instruction::SRem:
+      // Avoid introducing integer div/rem by undef to avoid undefined behavior.
+      for (int i = 0, e = Mask.size(); i != e; ++i)
+        if (Mask[i] == -1)
+          return false;
+      LLVM_FALLTHROUGH;
     case Instruction::Add:
     case Instruction::FAdd:
     case Instruction::Sub:
     case Instruction::FSub:
     case Instruction::Mul:
     case Instruction::FMul:
-    case Instruction::UDiv:
-    case Instruction::SDiv:
-    case Instruction::FDiv:
-    case Instruction::URem:
-    case Instruction::SRem:
     case Instruction::FRem:
     case Instruction::Shl:
     case Instruction::LShr:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69038.225216.patch
Type: text/x-patch
Size: 2932 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191016/a0f32509/attachment.bin>


More information about the llvm-commits mailing list