Skip to content

[ConstraintElimination] A miscompile in presence of shl nuw nsw and llvm.umin #78621

Closed
@DaniilSuchkov

Description

The following commit: 71f56e4
Triggered this miscompile: https://alive2.llvm.org/ce/z/oBg-u8

Now opt -passes=constraint-elimination -S turns

define i1 @test(i32 %arg) {
  %icmp = icmp slt i32 %arg, 0
  %shl = shl nuw nsw i32 %arg, 3
  %call4 = call i32 @llvm.umin.i32(i32 %shl, i32 80)
  ret i1 %icmp
}

declare i32 @llvm.umin.i32(i32, i32) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

into

define i1 @test(i32 %arg) {
  %shl = shl nuw nsw i32 %arg, 3
  %call4 = call i32 @llvm.umin.i32(i32 %shl, i32 80)
  ret i1 false
}

declare i32 @llvm.umin.i32(i32, i32) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

Given this debug output:

opt -passes=constraint-elimination before-constr-elim-renamed.ll -S -debug-only=constraint-elimination,constraint-system
Processing fact to add to the system: icmp ule i32 %call4, %shl
Adding 'icmp ule i32 %call4, %shl'
  constraint: -8 * %arg + %call4 <= 0

---
-1 * %arg <= 0
-8 * %arg + %call4 <= 0
-1 * %call4 <= 0
8 * %arg <= -1
unsat
Adding 'icmp sge i32 %call4, 0'
  constraint: -1 * %call4 <= 0

Adding 'icmp sle i32 %call4, %shl'
  constraint: -8 * %arg + %call4 <= 0

Processing fact to add to the system: icmp ule i32 %call4, 80
Adding 'icmp ule i32 %call4, 80'
  constraint: %call4 <= 80

Adding 'icmp sge i32 %call4, 0'
  constraint: -1 * %call4 <= 0

Adding 'icmp sle i32 %call4, 80'
  constraint: %call4 <= 80

Top of stack : 0 1
CB: 0 1
Processing condition to simplify:   %icmp = icmp slt i32 %arg, 0
Checking   %icmp = icmp slt i32 %arg, 0
---
-1 * %call4 <= 0
-8 * %arg + %call4 <= 0
-1 * %call4 <= 0
%call4 <= 80
-1 * %arg <= 0
sat
---
-1 * %call4 <= 0
-8 * %arg + %call4 <= 0
-1 * %call4 <= 0
%call4 <= 80
%arg <= -1
unsat
Condition icmp sge i32 %arg, 0 implied by dominating constraints
-1 * %call4 <= 0
-8 * %arg + %call4 <= 0
-1 * %call4 <= 0
%call4 <= 80

I'm not 100% sure if the aforementioned patch causes the miscompile, of if it merely triggers it on this specific reproducer. The fact that something like -1 * %call4 <= 0 is reported as a "dominating constraint" seems suspicious to a person who's not familiar with the logic of ConstraintElimination and it doesn't look directly related to that patch. However, if I replace the shl nuw nsw i32 %arg, 3 with mul nuw nsw i32 %arg, 8, the miscompile doesn't happen: https://alive2.llvm.org/ce/z/EL2bCh.

Metadata

Assignees

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions